zoukankan      html  css  js  c++  java
  • CORS(跨域资源共享) 笔记

    0 简介

    CORS(Cross-Origin Resource Sharing,跨域资源共享)是一种克服浏览器跨域HTTP请求限制的方法(PS:后端发起HTTP请求无跨域限制)。

    采用CORS实现浏览器的跨域请求,有两个条件:一是浏览器支持CORS机制,目前大多数浏览器都是支持的;二是服务器有针对CORS机制的配置逻辑。

    在浏览器端,是否通过CORS机制进行跨域请求,对于客户端编程来说是一样的,整个过程由浏览器执行,客户端代码无需额外的逻辑。

    浏览器发现AJAX(XMLHttpRequest)请求的是跨域资源时,就会自动添加一些header(比如表示请求来源的Origin首部),如果是非简单请求则还会多出一次Options的请求。

     

    1 浏览器区分简单请求与非简单请求

    浏览器将跨域请求分为两类:简单请求(simple request)与非简单请求(not-so-simple request)。

    同时满足以下条件,则为简单请求:

    a. 请求方法是以下三种方法之一:

    • HEAD
    • GET
    • POST

    b. HTTP请求的header不超出以下几种字段:

    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type,且只限于三个取值(application/x-www-form-urlencoded、multipart/form-data、text/plain)之一

    不满足上述条件的,则为非简单请求。

     

    2 浏览器发起请求

    对于简单请求,浏览器在请求的header中自动带上Origin(包括协议、域名、端口),直接发起跨域请求即可。

    对于非简单请求,浏览器会先执行一次预检(preflight)请求,询问服务器当前网页所在的域名,是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和首部。

    预检请求的HTTP动词是Options,浏览器会在预检请求中带上此次非简单请求的相关信息,主要是3个首部:

    • Origin:此次非简单请求来源页面URL中的协议、域名、端口信息
    • Access-Control-Request-Method:此次非简单请求的HTTP动词
    • Access-Control-Request-Headers:由逗号分隔,为此次非简单请求中除简单请求中首部外,额外发送的首部的名称

    浏览器只有得到预检请求的肯定答复后,才会发出正式的非简单请求(首部中会自动带上Origin);否则会报错。

     

    3 服务端处理预检请求

    首先是对预检请求的处理,服务器可以允许请求,也可以禁止请求。

    如果允许此次请求,则返回200,并在响应中带上如下几个CORS相关的首部,且响应首部的值必须包含预检请求中的首部值

    • Access-Control-Allow-Origin:允许请求的源

    • Access-Control-Allow-Methods:允许的HTTP动词。最好一次性返回所有支持的方法,而不单是浏览器请求的那个方法,这样可以避免多次"预检"请求。

    • Access-Control-Allow-Headers:允许的首部。同理,返回所有允许的首部。

    • Access-Control-Allow-Credentials:是否允许带上认证信息,首部值必为true。(若为false,则不需要在响应中带上该首部)

    • Access-Control-Max-Age:指定本次预检请求的有效期(单位为秒)。即允许缓存该条响应的时长,在此期间不用发出相同的预检请求。

    如果拒绝该请求,仍旧返回200,但响应中没有上述的几个首部,或者有首部但不包含请求中的首部值

    CORS首部设置最佳实践:

    在服务端设置响应的CORS首部时,首部值设置成预先配置好的值(一般用于正式环境),或是将响应首部值动态地设置成请求中的首部值(一般用于测试环境)。

    比如对于 Access-Control-Allow-Origin 首部,在测试时直接设置成星号“*”,或是请求中的Origin的值。但在正式环境中,安全起见最好设置成特定的值。

    如果在正式环境中,想在 Access-Control-Allow-Origin 首部中配置2个或多个值,不能直接用逗号分隔。一般做法是先把所有允许的Origin值存放在一个集合中,然后检查请求中的Origin是否包含在该集合中,若是则将 Access-Control-Allow-Origin 设置成对应Origin值,否则不添加 Access-Control-Allow-Origin 首部。

     

    4 服务端处理正式的请求 

    同样,对于正式的数据请求,服务端也可以允许或拒绝。

    允许请求的话,则在响应中带上跟预检请求响应中相同的CORS首部,且首部值包含请求中相关的首部值

    拒绝请求时,则响应中不带上相关的CORS首部,或是首部值不包含请求中的首部值。

     

    5 浏览器处理响应

    如果浏览器CORS请求的相关条件,服务端不能满足(如Origin值不被允许),则服务器会返回一个正常的200响应,但响应首部没有包含Access-Control-Allow-Origin字段,浏览器就会抛出一个错误,被 XMLHttpRequest 的 onerror 回调函数捕获。

    如果服务端允许CORS请求的所有条件,则返回的200响应中包含相关的CORS首部,浏览器正常处理响应数据。

     

    参考文档

  • 相关阅读:
    医学院现代教育技术中心(网络中心)研究
    计算机网络视频教程(上海交通大学)
    教育部普通高中信息技术课程标准成员介绍
    教育部普通高中信息技术课程标准
    数据库设计的三种范式
    普式游戏(pervasive game)
    帮你了解职业高中
    IP私有地址
    巧用组策略,让Windows登录更安全
    关闭SQL Server 2012智能感知代码提示功能
  • 原文地址:https://www.cnblogs.com/haycheng/p/12974376.html
Copyright © 2011-2022 走看看