1、什么时间会引起跨域问题
当请求的资源与当前所在页面的资源的服务器不同的域、协议或端口不同的时候,如http://192.168.3.122:8080 这样一个地址。
- 域不同,地址换成了 192.168.3.123
- 协议不同,http变成了https
- 端口不同,原来是8080,换成了8081
在以上这些情况就会引起跨域问题。跨域一般产生在js的代码中,src等路径一般可以直接访问跨域资源
2、跨域预检请求
在跨域满足以下条件的时候会产生跨域预检请求:
- 使用了下面任一 HTTP 方法:
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH - 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type (but note the additional requirements below)
DPR
Downlink
Save-Data
Viewport-Width
Width - Content-Type 的值不属于下列之一:
application/x-www-form-urlencoded
multipart/form-data
text/plain - 请求中的XMLHttpRequestUpload 对象注册了任意多个事件监听器。
- 请求中使用了ReadableStream对象。
以上条件会先触发OPTIONS跨域预检请求。
3、跨域的解决方案
前端解决方案
- iframe
随着近年来前端技术的飞跃发展以及移动互联网时代的洗礼,iframe的使用渐渐的不被建议,虽然也是一种跨域请求的解决方案,但这里就不再讲述,请读者自行查阅网上资料。 - jsonp
jsonp是比较常用的方法,我们假设a.com域名需要向b.com发起一个api请求(jsonp的一个缺点是,仅能接受GET方式) - postMessage跨域
- nodejs中间件代理跨域
- WebSocket协议跨域
后端解决方案
- nginx代理跨域
- 跨域资源共享(CORS)
跨域资源共享需要后端在返回头中设置如下信息:
- Access-Control-Allow-Origin
其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。 - Access-Control-Allow-Headers
Access-Control-Allow-Headers 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。 - Access-Control-Allow-Methods
Access-Control-Allow-Methods 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。 - Access-Control-Allow-Credentials
对于附带身份凭证的请求,如cookie,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者。
参考文章: