Google chrome devtools 如何使用CacheStorage导出保存在浏览器中的缓存文件?

Google chrome devtools 如何使用CacheStorage导出保存在浏览器中的缓存文件?,google-chrome-devtools,service-worker,recovery,cachestorage,Google Chrome Devtools,Service Worker,Recovery,Cachestorage,我有一个网站,它使用CacheStorage API使用服务人员保存各种文件。由于我无法控制的原因,这些文件中的很多都从加载它们的服务器上丢失了。然而,我刚刚意识到数百个文件已经被缓存在一个浏览器中,这个浏览器已经访问了很多年了(幸运的是,该站点在正常运行后没有清理缓存)。我可以使用chrome的开发工具预览文件,但当我单击“下载”时,它会尝试从服务器(不再存在)下载副本,而不是给我本地缓存的版本 一次性导出这些文件的最简单方法是什么(记住有几百个)?我可以完全访问运行浏览器的计算机以及运行站点

我有一个网站,它使用CacheStorage API使用服务人员保存各种文件。由于我无法控制的原因,这些文件中的很多都从加载它们的服务器上丢失了。然而,我刚刚意识到数百个文件已经被缓存在一个浏览器中,这个浏览器已经访问了很多年了(幸运的是,该站点在正常运行后没有清理缓存)。我可以使用chrome的开发工具预览文件,但当我单击“下载”时,它会尝试从服务器(不再存在)下载副本,而不是给我本地缓存的版本


一次性导出这些文件的最简单方法是什么(记住有几百个)?我可以完全访问运行浏览器的计算机以及运行站点/服务人员的域。它不需要是一个很好的解决方案,因为一旦文件被恢复,我计划学习大量的经验教训,以防止将来发生类似的事情。

CacheStorage API可以从普通的网页JavaScript以及服务人员访问,因此如果您在访问
window.caches
的服务器上创建网页,您应该能够从缓存中取出东西并做任何您想做的事情。一旦你有了
cache.keys()
,你就可以循环使用
match()
,它会返回对该请求的响应。然后,您可以将它们打印出来进行复制和粘贴(可能并不理想),将每一个都发布到保存它们的服务器上,或者类似的方式

以下是我在traintimes.org.uk上的一些普通JS;仅显示脱机页面的列表,但如果需要,它可能会获取实际的缓存条目


//打开页面缓存
缓存。打开(“页面”)
//获取其密钥(缓存的请求)
.then(cache=>cache.keys())
//我们只需要每个请求的URL
.then(请求=>reqs.map(r=>r.url))
//我们先要最新的(反向)
.then(URL=>(URL.reverse(),URL))
//我们不在乎域名
.then(url=>url.map(u=>u.replace(/^.*?uk/,''))
//我们希望他们是可点击的链接
.then(URL=>URL.map(u=>[
''。加入(“”))
//我们希望它们在页面上可见
。然后(URL=>
document.getElementById('offline-list').innerHTML=
“
  • ”+URL.join(“
  • ”)+“
  • ” );
    添加到CacheStorage API的响应存储在磁盘上。例如,MacOSX上的chrome将它们存储在
    ~/Library/Application Support/Google/Chrome/Default/Service Worker/CacheStorage
    。在这个目录中,每个域都有一个目录,在这些目录中,该域使用的每个特定缓存都有单独的目录。这些目录的名称(在两个级别上)看起来不是人类可读的,因此您可能需要搜索内容以找到您正在查找的特定缓存

    在每个缓存的目录中,每个响应都保存在不同的文件中。这些文件是二进制文件,包含各种信息,包括请求的URL(靠近顶部)和HTTP响应头(接近末尾)。在这两者之间,您将找到HTTP响应的主体

    提取主体并将其保存到其他地方可用的文件的确切逻辑将根据URL架构、文件格式等而有所不同。此bash脚本适合我:

    #!/bin/bash
    
    mkdir -p export
    for file in *_0
    do
        output=`LC_ALL=C sed -nE 's%^.*/music/images/artists/542x305/([^\.]*\.jpg).*%\1%p;/jpg/q' $file`
        if [ -z "$output" ]
        then
            echo "file $file missing music URL"
            continue
        fi
    
        if [[ $(LC_ALL=C sed -n '/x-backend-status.*404/,/.*/p' $file) ]]
        then
            echo "$file returned a 404"
            continue
        fi
    
        path="export/$output"
    
        cat $file | LC_ALL=C sed -n '/music\/images\/artists/,$p' | LC_ALL=C sed 's%^.*/music/images/artists/542x305/[^\.]*\.jpg%%g' | LC_ALL=C sed -n '/GET.*$/q;p' > $path
        echo "$file -> $path"
    done
    

    谢谢这个马修-它真的很有帮助!不幸的是,我忽略了一个细节(我后来才意识到这是相关的),那就是所讨论的文件来自不同的域,并且没有设置任何CORS头。