61

file 协议导致的跨域问题以及解决方案

 4 years ago
source link: https://www.tuicool.com/articles/7N3QFvF
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

EJzQryM.jpg!web

问题复现:

学习 ES6 模块化的时候,写了这段代码:

<script src="./aaa.js" type="module"></script>
<script src="./bbb.js" type="module"></script>
<script src="./aaa2.js" type="module"></script>

结果跑到 chrome 下面一看,报错了:

qaiMbiy.png!web

看起来是跨域问题,也就是只支持 httphttps 等这种类型的跨域请求,不支持 file 协议类型的(直接本地打开文件)。解决方案如下:

1.给 chrome 快捷方式添加参数:

–allow-file-access-from-files

实测无效。貌似还得重启电脑,太麻烦了,遂放弃。

2.换浏览器。经过测试,Edge 可以正常显示,但 FireFox 还是报跨域错误:

NbMzYvi.png!web

3.用 IDE。像 Webstrom 这类型的 IDE 是内置 http 服务器的,这样可以不通过 file 协议打开文件,不过这个还是有点麻烦,我没尝试。

4.使用热更新插件。刚好想起编辑器里安装了 live server 这个插件,这个其实是做同步刷新用的,但是由于它可以在本地开启一个服务器,所以可以利用这一点(localhost 访问)。尝试之后发现确实不报错了。

5.Node 开一个服务器

// server.js
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.get('/',function (req,res) {
    res.send('./index.html',{root:__dirname});
})
app.listen(8203);

问题是解决了,但总觉得心里不踏实,所以开始了艰苦的 google 之旅,最后算是找到了问题的根源。但我还是想从同源策略开始解释:

同源策略(Same origin policy),是出于安全而诞生的一种约定,规定了只能在本域内进行资源访问。所谓同源是指”协议+域名+端口”三者相同。

不同源之间进行资源访问,就需要跨域。特殊地,有三个标签默认是允许跨域加载资源的:

<img src="xxx">
<link href="xxx">
<script src="xxx">

关键来了,ES6 使用模块的时候要在标签中声明 type="module" ,而这类 使用了模块的 script 是受限于同源策略的 。我们尝试改动之前的代码如下:

<script src="./aaa.js" type="module" defer="defer"></script>
<script src="./bbb.js" type="module" defer="defer"></script>
<script src="./ccc.js" type="text/javascript" defer="defer"></script>

3IZbEny.png!web

可以看到,前面两个 script 使用了模块, Sec-Fetch-Mode 都是 cors ,而最后一个就是常规的引入脚本,不受同源策略影响,因此是 no-cors

我们可以理解为前两个 scirpt 发送了 Cors 跨域资源请求,而这种请求要求 request header 的 origin 必须合法 —— 也就是必须带有 httphttps 等,以用来表明请求源。

但是别忘了,我们现在是在本地打开文件,使用的不是 http 协议,而是 file 协议,它根本就没有跨域请求需要的 origin (注意看上图, origin 是空的)。所以,这种情况就要报错了。其实从报错信息中也能读出这一点。

那么,我们现在用 live server 在本地开启服务器,再看一下控制台:

2Uf6Z3r.png!web

可以看到,因为这次不是用 file 协议访问了,所以一切正常。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK