为什么使用 ES6 模块化的时候会有跨域问题?

代码如下:

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

引入了三个js文件,内部使用了 ES6 的模块化语法,结果在chrome里报错了:
QQ截图20191013105236.png
这里是使用了 file 协议,所以本地服务器打开文件(http协议)就不会报错了。但是我不太清楚为什么会出现跨域问题?

阅读 12.2k
4 个回答

咱们知道,script标签是自带跨域的功能的,这也就是为什么在某些场合会通过jsonp并结合script来请求资源。

其次,跨域导致的原因是协议、域名、端口号不同就会导致,而这里的协议通常是指http协议,https等协议。也就是说http, data, chrome, chrome-extension, https这些协议是支持跨域请求的,而file协议并不支持。

file协议:本地文件传输协议,主要的目的就是用于访问本地计算机中的文件,好比通过Windows的资源管理器中打开文件或者通过右键单击‘打开’一样。然后通过file:///文件路径这样的形式去访问。那么file协议和http协议有啥区别,浏览器通过file://访问文件和http://访问文件的区别

  • file协议用于访问本地计算机中的文件,好比通过资源管理器中打开文件一样,需要主要的是它是针对本地的,即file协议是访问你本机的文件资源。
  • http访问本地的html文件,相当于将本机作为了一台http服务器,然后通过localhost访问的是你自己电脑上的本地服务器,再通过http服务器去访问你本机的文件资源。
  • 再简单点就是file只是简单请求了本地文件,将其作为一个服务器未解析的静态文件打开。而http是在本地搭建了一个服务器再通过服务器去动态解析拿到文件。

而当你在某盘符位置下直接打开一个网页(script标签中引入了某地的某个js文件),则在浏览器地址栏呈现如下:file:///D:/MyStudyProject/JSTopLevel/chapter-9/2%E5%AF%BB%E6%89%BE%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%87%8C%E5%B8%A6%E5%BC%95%E5%8F%B7%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2.html,则会出现跨域问题。而http、https等协议支持跨域请求。所以解决办法就是通过搭建本地一个服务器去进行资源的问题来解决跨域问题。

ES6 使用模块的时候要在标签中声明 type="module",而这类使用了模块的 script 是受限于同源策略的,默认会发起cors跨域请求,问题来了,这种请求要求 request header origin 必须带有 http 等类型,但是 file 协议下,origin 是空的,也就是不符合这个要求,如果在这种情况下依然要发送请求,那就会报错了。

新手上路,请多包涵

启动serve服务是可以的,但是项目发布怎么办呢,在服务器也启动serve服务吗,但是我的web服务是用的Tomcat,两者之间会有冲突吗

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题