美文网首页跨域问题
CORS 解决跨域的一般用法

CORS 解决跨域的一般用法

作者: forever_youyou | 来源:发表于2019-02-13 16:39 被阅读0次

详情参见: MDN HTTP访问控制 (CORS)

常用设置(一般情况够用了)

XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求

后端响应头设置:

  • 配置允许跨域访问的源: Access-Control-Allow-Origin: <origin> | *
    • 允许所有源: Access-Control-Allow-Origin: *
    • 配置指定的源: Access-Control-Allow-Origin: http://mozilla.com
    • 不能同时指定多个源, 如有需要可以通过代码动态控制
  • 配置允许跨域访问的请求方法: Access-Control-Allow-Methods: <method>[, <method>]*
  • 配置允许跨域访问的请求头: Access-Control-Allow-Headers: <field-name>[, <field-name>]*

如果需要附带身份凭证(携带cookie)则需要如下额外配置:

  • 后端增加响应头: Access-Control-Allow-Credentials: true , 其中值固定为 true;
  • 前端请求库增加对应设置; (如axios中需要设置 withCredentials: true 即可发送cookie);
  • 对于这种附带身份凭证的请求, 服务器的 Access-Control-Allow-Origin 不能 设置为 *, 必须指定具体的origin;

代码动态控制允许多个域(以php为例)

// 允许跨域的origin白名单, 为空则允许所有origin跨域
$allowOrigin = []; // 如: ['http://localhost:8080', 'https://host:8081']
// 跨域访问的时候才会存在该字段
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
// 有配置白名单且当前origin在白名单
if (!empty($allowOrigin) && in_array($origin, $allowOrigin)) {
    header("Access-Control-Allow-Origin: {$origin}");
}

注:
IE 10 提供了对规范的完整支持,但在较早版本(8 和 9)中,CORS 机制是借由 XDomainRequest 对象完成的。


扩展阅读(摘自MDN)

什么情况下需要 CORS ?

跨域资源共享标准( cross-origin sharing standard )允许在下列场景中使用跨域 HTTP 请求:

  • XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求。
  • Web 字体 (CSS 中通过 @font-face 使用跨域字体资源), 因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。
  • WebGL 贴图
  • 使用 drawImage 将 Images/video 画面绘制到 canvas
  • 样式表(使用 CSSOM)

简单请求

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 Fetch (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

  • 使用下列方法之一:
    • GET
    • HEAD
    • POST
  • Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (需要注意额外的限制)
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  • Content-Type 的值仅限于下列三者之一:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded
  • 请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器;XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。
  • 请求中没有使用 ReadableStream 对象。

预检请求

即好多同学初次接触感到奇怪的 OPTIONS 请求

与前述简单请求不同, “需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

当请求满足下述任一条件时,即应首先发送预检请求:

  • 使用了下面任一 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 对象。

相关文章

网友评论

    本文标题:CORS 解决跨域的一般用法

    本文链接:https://www.haomeiwen.com/subject/eepdeqtx.html