服务器不接收跨域文件,file 协议导致的跨域问题以及解决方案

0feb07d73eb696bacd620b8a8a196d9c.png

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

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

2c074ca0eee4b56ce179a0984d58ab54.png

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

1.给 chrome 快捷方式添加参数:–allow-file-access-from-files实测无效。貌似还得重启电脑,太麻烦了,遂放弃。

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

28cee15ac7f31160db665f61a9d63b0a.png

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),是出于安全而诞生的一种约定,规定了只能在本域内进行资源访问。所谓同源是指"协议+域名+端口"三者相同。

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

xxx

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

a1490764917b608d94de98490ff19f2d.png

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

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

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

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

37d5365f1715c6bf20b7bc31f0b5f6ff.png

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

参考:

Understanding ES6

ModulesES6 module support in Chrome 62/Chrome Canary 64, does not work locally, CORS error

Access to Image from origin 'null' has been blocked by CORS policy

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值