最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • HTTP 跨域资源共享

    正文概述 转载于:掘金(ezy)   2021-01-12   404

    跨域资源共享(CORS, Cross-Origin Resource Sharing) 是浏览器的机制,让浏览器可以合理避开浏览器同源策略的限制,以访问不同源上的资源。

    跨域请求

    访问不同的域、协议或端口的资源时,浏览器会发起一个跨域请求。

    以下展示了从 http://www.a.com/page.html 访问不同资源的情况

    // 不同文件,不跨域
    http://www.a.com/other.html 
    // 不同目录,不跨域
    http://www.a.com/path/other.html
    
    // 不同协议,跨域 
    https://www.a.com/other.html 
    
    // 不同端口,跨域 
    http://www.a.com:8080/other.html
    
    // 不同域名,跨域 
    http://www.b.com/other.html
    // 不同域名(父域名),跨域 
    http://a.com/other.html
    // 不同域名(子域名),跨域 
    http://sub.a.com/other.html
    // 不同域名(ip),跨域 
    http://119.254.98.162/other.html
    

    预检请求(preflight request)

    浏览器在发起跨域请求前会先使用 OPTIONS 方法发起一个预检请求,以获知服务器是否允许该跨域请求,服务器确认允许后才发起正式 HTTP 请求。

    在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证。

    简单请求

    浏览器将跨域请求分为简单请求与非简单请求,简单请求不需要触发预检请求

    满足发下条件会被视为简单请求:

    • 使用下列请求方法之一:
      • GET
      • HEAD
      • POST
    • 请求头信息不超出以下几种:
      • Accept
      • Accept-Language
      • Content-Language
      • Content-Type 仅限于以下三者
        • text/plain

        • multipart/form-data

        • application/x-www-form-urlencoded

    简单请求会在请求头添加 Origin 字段,服务器根据这个值来决定是否同意这次请求。

    如果同请求,服务器响应会额外添加几个字段:

    • Access-Control-Allow-Origin(必须) 指定了允许访问该资源的域,其值要么是请求时 Origin 的值,要么是 * 表示接受任意域名的请求; 当指定的值不是 * 时,响应首部中的 Vary 字段的值必须包含 Origin;
    • Access-Control-Allow-Credentials(可选) 当浏览器的credentials设置为true时,是否允许浏览器读取response的内容; 返回true(唯一有效值,区分大小写)则可以,其他值均不可以。 此字段返回true时,Access-Control-Allow-Origin 必须为请求 Origin 的值,不能是 *; 此字段在预检请求的响应中时,它指定了实际的请求是否可以使用credentials; 简单请求不会被预检,当浏览器的credentials设置为true时,其响应中如果不包含该字段,浏览器将无法读取response的内容。
    • Access-Control-Expose-Headers(可选): 白名单,列出了服务器允许浏览器访问的头; 默认情况下,XMLHttpRequest.getResponseHeader() 方法只能拿到六种简单响应首部,如果想要能拿到其它字段,就需要在Access-Control-Expose-Headers指定。 六种简单响应首部是:
      • Cache-Control
      • Content-Language
      • Content-Type
      • Expires
      • Last-Modified
      • Pragma

    非简单请求

    非简单请求是那种对服务器有特殊要求的请求

    比如请求方法是 PUTDELETE; 比如包含了限定以外的请求头,如 AuthorizationX-Custom-Header; 比如 Content-Type 字段值是 application/json;

    对于非简单请求,浏览器会先发起一个预检请求,得到肯定答复后,才会发起正式请求。

    预检请求

    预检请求使用 OPTIONS 方法,包括以下字段:

    • Origin: 表明实际请求的源站;
    • Access-Control-Request-Method: 表明实际请求所使用的 HTTP 方法;
    • Access-Control-Request-Headers: 表明实际请求所额外携带的头部字段;

    注:预检请求由浏览器自动发出,无须手动设置这些字段。

    预检请求的响应

    服务器收到预检请求后,检查了 Origin, Access-Control-Request-Method, Access-Control-Request-Headers 后,可以确认是否允许跨源请求,然后做出回应。

    响应包括以下字段:

    • Access-Control-Allow-Origin 指定了允许访问该资源的域,含义同简单请求
    • Access-Control-Allow-Methods 指定了实际请求中允许使用的所有HTTP方法
    • Access-Control-Allow-Headers 指定了实际请求中允许携带的所有首部字段
    • Access-Control-Allow-Credentials 指定了实际的请求是否可以使用credentials,含义同简单请求
    • Access-Control-Max-Age 指定了预检请求的结果能够被缓存多久,单位秒

    正常跨域请求

    通过预检后,正常跨域请求跟简单请求一样,浏览器会在请求头添加 Origin 字段;

    服务器的回应也跟简单请求一样,必须包含 Access-Control-Allow-Origin 字段。

    PHP 跨域中间件

    支持php-PSR规范的跨域资源共享(cors)中间件。

    安装依赖

    composer require reezy/cors 
    

    配置

    <?php
    
    return [
        // 是否允许所有的域
        'allowed-all-origins'   => env('APP_ENV') !== 'prod',
        // 允许访问该资源的域
        'allowed-origins'       => ['http://localhost'],
        // 实际请求中允许携带的所有首部字段
        'allowed-headers'       => ['authorization', 'content-type', 'x-requested-with'],
        // 实际请求中允许使用的所有HTTP方法
        'allowed-methods'       => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], // ex: GET, POST, PUT, PATCH, DELETE
        // 实际的请求是否可以使用credentials
        'allowed-credentials'   => true,
        // 白名单,列出了服务器允许浏览器访问的头
        // 六种简单首部不需要指定:Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma
        'exposed-headers'       => [ ],
        // 预检请求的结果能够被缓存多久,单位秒
        'max-age'               => 10 * 86400,
    ];
    

    参考

    HTTP访问控制(CORS)
    developer.mozilla.org/zh-CN/docs/…
    浏览器的同源策略
    developer.mozilla.org/zh-CN/docs/…


    起源地 » HTTP 跨域资源共享

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元