什么是跨域?
跨域不是问题,是一种安全机制。浏览器有一种策略名为同源策略,同源策略规定了部分请求不能被浏览器所接受。
值得一提的是:同源策略导致的跨域是浏览器单方面拒绝响应数据,服务器端是处理完毕并做出了响应的。
什么是同源策略
一个url由三部分组成:协议,域名(ip地址),端口。
只有当协议,域名,端口都一致的时候,才被称为同源。
而同源策略规定,只有发送请求的那一边和接受请求的那一边处于同源的情况下,浏览器才会接受响应。
举个例子
而当我们的请求不符合同源策略的时候。往往会出现以下错误👇
解决跨域常见的5种方法
第一种:JQuery的ajax(推荐JQuery项目中使用)
jq的ajax自带解决跨域的方法。底层原理采用的JSONP的跨域解决方案。如下
在JQ项目中,这是最常见的解决方案。
第二种:script标签解决跨域(远古Web项目中使用)
如果你的项目是祖传下来的。没有框架连JQuery都没有。没关系,我们可以尝试使用原生的方法去解决。
原生采用的是script标签可以不受跨域限制的特性来实现跨域。
这里需要注意的是,使用完请求之后记得删除script,否则会随着请求的变多script标签会一直挂载在DOM上。
在远古的web中,这是一种方案。但现在已经不用了。
vue/react/jq等框架性项目中不要使用这种方法,不是不行,只是有更好的选择
第三种:前端代理解决跨域
每一个框架的代理配置都不太一样。这里仅以我使用的umi.js(react)为例。
Umi.js框架会有 config.ts / config.js 文件,文件中会有proxy字段、字段按图中配置方法。即可完成跨域
第四种:服务端代理(Nginx代理)
nginx代理一般使用在生产环境。是服务端解决跨域的一种方案。
简单配置模板👇
注意,nginx配置完代理后需要重启nginx,nginx代理是生产环境的常用方案
第五种:后台(逻辑层)添加响应头解决
Access-Control-Allow-Origin响应头的意思是,安全同行的请求。
举个例子 http://192.168.0.103:8080 向http://192.168.0.102:8080 发送了请求,结果因为域名不一样,在返回信息的时候因为IP地址不一致被拦截。
但是如果http://192.168.0.102:8080 在响应头中的 Access-Control-Allow-Origin 字段中携带上属性值'http://192.168.0.103:8080' 如下
这就等于告诉浏览器,http://192.168.0.102:8080 这个地址是安全的,请不要拦截。
这样,http://192.168.0.103:8080 就可以接受来自 http://192.168.0.102:8080 返回的信息。
当然,我们也可以进行所有域名均不拦截的设置(如下)
node案例如下
并不建议此种方案,因为安全性不高。自己写小练习的时候建议使用,因为真的很方便。
总结
跨域的常见的五种解决方案如下
- jsonp,代表:jquery的$.ajax。(仅限JQuery项目使用)
- script标签解决跨域(远古web使用的方案,已不建议使用)
- 前端代理
- nginx代理
- 设置响应头(不建议使用,安全性不高,小练习可以用用,方便)