如果我们把一个本地文件夹拖到浏览器里打开,大部分浏览器应该都会显示里面的文件和文件夹。就像这样:
这样的地址是本地文件协议,url 如:
file:///C:/
如果可以通过在浏览器里运行 js 代码,请求本地文件的 url,并且可以任意遍历、读取文件(也就是全盘扫描了),那太可怕了。
我的常识告诉我,浏览器出于安全原因肯定会阻止这一行为,所以这应该是不可行的。在普通的网页里请求本地文件确实不可行,但是在浏览器扩展的后台脚本里呢?今天 Reinford 告诉我在后台脚本里可以任意请求本地文件,我试了下还真可以。
Chrome 扩展在开发者模式下可以读取任意本地文件
浏览器里是不允许跨域的,如果服务器没有指定 Access-Control-Allow-Origin
字段,那么浏览器会阻止向服务器发起的任何跨域请求。
如果服务器指定了 Access-Control-Allow-Origin
,则浏览器会根据它的设置,只允许它指定的那些域名进行跨域请求。
特别的,如果 Access-Control-Allow-Origin
的值是 *
,表示服务器接受任意跨域请求。
以前,如果我们制作了一个 Chrome 扩展,它的前台、后台代码都可以无视跨域限制,因为扩展有特权嘛。但是从 Chrome 85 开始,扩展的前台不允许跨域了,只允许后台跨域。
但是后台可以修改网络请求,我们给每个请求的 response headers 都添加 Access-Control-Allow-Origin : *
,那么前台发出的所有请求都可以跨域。
Chrome 扩展允许任意跨域的办法
我在 Chrome 扩展里修改了前台页面的请求,把 referer 和 origin 都修改了。但是请求还是因为跨域问题失败了。在失败的错误信息里,看到 origin 是修改之前的原本的 origin。
Fetch 请求的 request origin
Windows 中有一些字符不能做文件名:
\ / : ? " < > * |
但是 Chrome 的下载 api 里,有更多的字符不能做文件名,否则下载会失败。这些字符里大多是控制字符。
Chrome 扩展下载文件时,不能使用的字符可以建立一个正则表达式,对文件名进行替换:
// 不安全的字符,是 Chrome 和 Windows 不允许做文件名的字符 const notSafeString = `[\u0001-\u001f\u007f-\u009f\u00ad\u0600-\u0605\u061c\u06dd\u070f\u08e2\u180e\u200b-\u200f\u202a-\u202e\u2060-\u2064\u2066-\u206f\ufdd0-\ufdef\ufeff\ufff9-\ufffb\ufffe\uffff\\\/:\?"<>\*\|~]` const safeFileName = new RegExp(notSafeString, 'g') // 安全的文件名
这些字符是 Reinford 测试出来的,测试结果的文件:
链接: https://pan.baidu.com/s/1y8AVKGmasV1ZYiCErwc1Zg 提取码: q41v
此外,还有一些情况要处理。
1. Chrome 不允许文件夹和文件名的开头、结尾使用点 .
。
2. 路径首尾不允许有空格。
3. 路径中出现多个斜线会报错,如 download//a.jpg
。
Chrome 扩展下载文件时,不能使用的字符
通过 chrome.webRequest.onBeforeSendHeaders 事件来设置 referer,来达到跨域的目的。
1. 在 manifest.json 中声明权限
"permissions": [ "tabs", "downloads", "webRequest", "webRequestBlocking", "*://www.pixiv.net/*", "*://www.pixivision.net/*", "*://i.pximg.net/*" ]
webRequest、webRequestBlocking 是必须的;后面的网址列表表示这个扩展的生效范围。
在做跨域的时候,需要把你的目标网址也添加进去。比如你的扩展运行在 a.com,去请求 b.com 的内容,那么这两个网址都要写进去。
Read More →
Chrome 扩展修改 referer 实现跨域
本文略微记录一下开发chrome扩展的经验,免得以后用到了还要再去查一遍文档。注意这不是教程,只是一点人生的经验……教程可以参考这里。
1.文件结构:
在扩展的根目录必须有个manifest.json文件,这个文件很重要,参数可以去文档里看。
其他的所有文件可以放在根目录,也可以建立文件夹存放。
扩展的图标可以用jpg或者png格式;官方建议是不要把图标占满画布,而是在四周留下一点空白。
一般我们需要一个在后台默默运行的js,通常叫做background.js,它能使用所有chrome扩展的API。
通常我们也需要有一个在前台运行的js,可以叫做content.js。这个js会被加载进前台页面执行,它只能使用很少的chrome扩展的API。而且它通常只能访问dom结构,不能直接使用页面上定义的函数。
如果需要也可以建立一个活动页面,一般叫做popup.html。
如果需要也可以建立一个选项页面,一般叫做options.html。
以上这些都需要在manifest.json里定义。
其他的文件可以自行发挥,比如html文件、css文件、图片等,有需要就可以建立,然后自行调用即可。
在background的参数里设置"persistent": false可将扩展作为event page,可以减少一些内存占用。
Read More →