跨域资源共享是什么
CORS是什么
CORS全称为Cross-Origin Resource Sharing,被译为跨域资源共享,新增了一组HTTP首部字段,允许服务器声明哪些源站有权限访问哪些资源。
跨域资源共享标准规范要求,对那些可能对服务器数据产生副作用的HTTP请求方法(特别是GET
以外的HTTP请求,或者搭配某些MIME类型的POST
请求),浏览器必须首先使用OPTIONS
方法发 起一个预检请求,从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的HTTP请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证。
跨域资源共享机制的工作原理主要应用于三个场景;
- 简单请求
- 预检请求
- 认证请求
简单请求
简单请求是什么
请求满足所有下迹条件,则该请求可视为“简单请求”:
- 使用下列请求方法之一:
GET
、HEAD
或POST
- 不得人为设置下列集合之外的其他首部字段:
Accept
、Accept-Language
、Content-Language
、Content-Type
Content-Type
的值仅限于下列三者之一:text/plain
multipart/form-data
application/×一www-forrn-urlencoded
值得注意的是,这些跨域请求与浏览器发出的其他跨域请求并无二致。如果服务器未返回正确的响应首部,则请求方不会收到任何数据。因此,那些不允许跨域请求的网站无需为这一新的HTTP访问控制特性担心。
请求消息
以下是请求消息示例:
GET/resources/public-data/HTTP/1.1
Host:bar.other
User-Agent: Mozilla/5.0(Macintosh; U; Intel Mac OS×10.5;en-US;rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=O.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=o.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
origin: http://foo.example
请求首部字段Origin
表示该请求来源于http:/foo.exmaple,Origin
的值是每次发送请求时自动携带的请求首部消息。
响应信息
以下是响应消息示例:
HTTP/1.1200 OK
Date: Mon,o1 Dec 2008 00:23:53 GMT
server: Apache/2.0.61
Access-Control-Allow-Origin:*
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
[XML Data]
响应中携带了响应首部字段Access-Control-Allow-Origin
,使用Origin
和Access-Control-Allow-Origin
就能完成最简单的访问控制。
本例中,服务端返回的Access-Control-Allow-Origin:*
表明该资源可以被任意外域访问。
预检请求
预检请求是什么
当请求满足下述任一条件时,即应首先发送预检请求:
- 使用下列请求方法之一:
PUT
、DELETE
、CONNECT
、OPTIONS
、TRACE
或PATH
- 不得人为设置下列集合之外的其他首部字段:
Accept
、Accept-Language
、Content-Language
、ContentType
Content-Type
的值仅限于下列三者之一:text/plain
multipart/form-data
application/×-www-forrm-urlencoded
预检请求要求必须首先使用OPTIONS
方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。
预检请求可以避免跨域请求对服务器的用户数据产生未预期的影响。
请求消息
以下是OPTIONS
预检请求消息示例:
OPTIONS /resources/access-control-with-post-preflight/HTTP/1.1
Host: aruner.net
User-Agent:Mozilla/5.0(Macintosh; U;Intel Mac OS10.5;en-US;rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;g=0.9,*/*;q=.0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflateKeep-Alive: 300
Connection: keep-alive
Origin: http://arunranga.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGARUNER
- 请求首部字段
Access-Control-Request-Method
表示该请求使用POST
方法。 - 请求首部字段
Access-Control-Request-Headers
表示该请求携带X-PINGOTHER
首部字段。
响应消息
以下是OPTIONS
预检请求的响应消息示例:
HTTP/1.1 200 OK
Date:Mon,o1 Dec 2008 01:15:39 GMT
Access-Control-Allow-Origin: http://arunranga.com
Access-Control-Allow-Methods: POST,GET,OPTIONS
Access-Control-Allow-Headers: X-PINGARUNER
Access-Control-Max-Age: 1728000
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
- 响应首部字段
Access-Control-Allow-Methods
表示允许POST
、GET
和OPTIONS
请求方法。 - 响应首部字段
Access-Control-Allow-Headers
表示允许请求携带首部字段X-PINGOTHER
。 - 响应首部字段
Access-Control-Max-Age
表示设置响应有效时间为1728000秒。
认证请求
认证请求是什么
CORS具有一个有趣的特性是,可以基于HTTP Cookies和HTTP认证信息发送身份凭证。一般而言,对于跨域XMLHttpRequest请求,刘览器不会发送身份凭证信息。如果要发送凭证信息,需要设置XMlLHttpRequest的某个特殊标志位。
xmlHttpRequest.withCredentials = true;
将XMLHttpRequest的withCredentials
标志设置为true
,使得向服务器发送Cookies,服务器返回响应首部字段Access-Control-Allow-Credentials: true
。
如果服务器端的响应中未携带Access-Control-Allow-Credentials: true
,浏览器将不会把响应内容返回给请求的发送者。
请求消息
以下是请求消息示例:
GET/resources/access-control-with-credentials/HTTP/1.1
Host: bar.other
User-Agent:Mozilla/5.0o(Macintosh; U; Intel Mac OS×10.5;en-US;rv:1.9.1b3pre)Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml.application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/credential.html
Origin: http://foo.example
Cookie: pageAccess=2
该请求携带了请求首部字段Cookie的相关信息。
响应消息
以下是响应消息示例:
HTTP/1.1 200 OK
Date: Mon,o1 Dec 200801:34:52 GMT
Server:Apache/2.0.61(Unix)PHP/4.4.7 mod_ss/2.0.61 OpenSSL/0.9.7e mod_fastcg/2.4.2 DAV/2SVN/1.4.2
x-Powered-By: PHP/5.2.6
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-200801:34:53 GMT
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 106
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain