Introduction
Cross-domain is a question I often ask in daily interviews. This word appears frequently in the front-end world. The main reason is due to security restrictions (same-origin policy, that is, JavaScript or cookies can only access content under the same domain) , Because we inevitably need to perform cross-domain operations in daily project development, cross-domain capability is also one of the basic skills of front-end engineers.
Like most cross-domain solutions, JSONP is also my choice. However, one day the requirements of PM have changed, and a certain function needs to be changed to support POST, because the amount of data transmitted is relatively large, and the GET form cannot be handled. So I tossed the long-known CORS (Cross-Origin Resource Sharing, Cross-Origin Resource Sharing)
What CORS can do:
The normal use of AJAX will require normal consideration of cross-domain problems, so great programmers have tossed out a series of solutions to cross-domain problems, such as JSONP, flash, ifame, xhr2 and so on.
The CORS introduced in this article is a set of solutions to AJAX cross-domain problems.
The principle of CORS:
CORS defines a mechanism for cross-domain access, which enables AJAX to achieve cross-domain access. CORS allows web applications on one domain to submit cross-domain AJAX requests to another domain. Implementing this functionality is as simple as sending a response header by the server.
two requests
Browsers divide CORS requests into two categories: simple requests and not-so-simple requests.
As long as the following two conditions are met at the same time, it is a simple request.
(1) The request method is one of the following three methods: HEAD GET POST (2) HTTP header information does not exceed the following fields: Accept Accept-Language Content-Language Last-Event-ID Content-Type: limited to three values application/x-www-form-urlencoded, multipart/form-data, text/plain
Anything other than the above is a non-simple request
simple request
The browser will automatically bring an Origin header
GET /cors HTTP/1.1 Origin: http://localhost:8080 Host: api.alice.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
If the server allows this response it returns the following:
Access-Control-Allow-Origin: http://localhost:8080 Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: myheader Content-Type: text/html; charset=utf-8
non-simple request
First, an OPTIONS pre-check request will be triggered
The request headers sent are as follows
OPTIONS /ajax.php HTTP/1.1 Origin: http://localhost:8080 Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-Custom-Header Host: localhost:8080 Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
The response sent by the server:
HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:39 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: http://localhost:8080 Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Content-Length: 0 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain
Request headers and response headers in CROS
request header
request header | meaning |
Origin | 本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求 |
Access-Control-Request-Method | 该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法 |
Access-Control-Request-Headers | 该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段 |
响应头
响应头 | 含义 |
Access-Control-Allow-Origin | 该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求 |
Access-Control-Allow-Methods | 该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求 |
Access-Control-Allow-Headers | 如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段 |
Access-Control-Allow-Credentials | 它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器 |
Access-Control-Max-Age | 该字段可选,用来指定本次预检请求的有效期,单位为秒。如果填1728000,即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求 |
Access-Control-Expose-Headers | CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定 |
使用反向代理服务器可以解决跨域问题
比如将前端代码部署到nginx上,这样访问的地址是localhost:8080/test/aa.html
假设之前访问的跨域地址是 http://10.0.0.123:8080/hello/go
然后前端将 http://10.0.0.123:8080/hello/go 改成 http://localhost:8080/hello/go 这样就是同源了,浏览器就会将session,cookie都带上请求也放行了
之后nginx将访问/hello/go的这个url改写成 http://10.0.0.123:8080,然后nginx去请求这个真实的跨域地址获取数据后返回,这样就解决了跨域问题了
参考