美文网首页跨域问题
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