跨域
不同站点可以互相请求,不同的源(socket = ip+port)就是跨域
造成需要跨域的两种策略
浏览器同源策略,导致了需要跨域解决。
同源策略:
- DOM(html标签)同源策略:浏览器禁止对不同源DOM进行操作。主要是iframe,不同源的iframe是限制互相访问的
- XmlHttpRequest同源策略:禁止使用XHR对象对不同源的服务器地址发起HTTP请求
为什么要有跨域限制
AJAX同源策略
因为web上标记登录信息的都是使用客户端存放的cookie,如果不同源能互相访问,B站点拿着A站点的cookie信息就等于是拿到了当是的账号密码。具体实例:
- 用户登录
bank.com
,bank_cookie产生了 - 用户不小心访问了恶意网站
virus.com
,从客户端获取了bank_cookie,网站携带着bank_cookie向bank.com
发起了AJAX请求 - bank的服务器端验证cookie,验证用户信息无误,返回信息给
virus.com
,信息泄露
DOM同源策略
如果iframe之间可以跨域访问
- 做个跟
bank.com
一样的假网站,两个iframe,一个是bank iframe
(这个占全屏),一个是virus iframe
。 bank DOM
输入登录信息,如果virus DOM
可以不同源,那么就能获得用户输入的登录信息
跨域方法
CORS跨域资源共享
通过nginx服务器返回响应头
简单请求
请求头
浏览器发出cors请求,请求头上带着origin
字段
GET /index HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
响应头
server通过Origin
字段来判断是否同意这次请求
-
如果域名在许可范围内,响应头多加几个字段
Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: FooBar Access-Control-Request-Method: PUT Content-Type: text/html; charset=utf-8
-
Access-Control-Allow-Origin
允许请求域名,同请求头的
origin
字段,如果任意域名都接受那么付*
值 -
Access-Control-Allow-Credentials
bool值,是否允许客户端请求携带cookie值
-
Access-Control-Expose-Headers
字段可选,Cors请求时,请求头只能有6个基本字段
Cache-Control
、Content-Language
、Content-Type
、Expires
、Last-Modified
、Pragma
,如果还需要其他的字段只能赋值到此字段中
非简单请求
非简单请求是 对服务器有特殊要求的 请求。比如要求是
PUT
或POST
或Content-Type
的值是application/json
。非简单请求会在正式通信前,增加一次http查询请求,称为
预请求
预请求-请求头
OPTIONS /cors HTTP/1.1 Origin: http://api.bob.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-Custom-Header Host: api.alice.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0...
-
Access-Control-Request-Method
该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是
PUT
。 -
Access-Control-Request-Headers
该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是
X-Custom-Header
。
预请求-响应头
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://api.bob.com 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
-
Access-Control-Allow-Methods
server允许的请求方法
-
Access-Control-Allow-Header
如果浏览器预请求头包含
Access-Control-Request-Headers
,则响应头必须包含Access-Control-Allow-Headers
,表示允许的头字段 -
Access-Control-Max-Age
字段可选,预请求的有效时间,秒是单位
-
服务器代理
浏览器有跨域限制,但是服务器是没有的,通过代理服务器返回资源服务器的响应体