一、什么是跨域?
跨域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com 页面去请求 www.google.com 的资源。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域。
二、为什么要限制跨域?
原因就是安全问题:如果一个网页可以随意地访问另外一个网站的资源,那么就有可能在客户完全不知情的情况下出现安全问题。比如下面的操作就有安全问题:
1、用户访问www.mybank.com ,登陆并进行网银操作,这时cookie啥的都生成并存放在浏览器
2、用户突然想起件事,并迷迷糊糊地访问了一个邪恶的网站 www.xiee.com
3、这时该网站就可以在它的页面中,拿到银行的cookie,比如用户名,登陆token等,然后发起对www.mybank.com 的操作。
4、如果这时浏览器不予限制,并且银行也没有做响应的安全处理的话,那么用户的信息有可能就这么泄露了。
三、为什么要跨域?
既然有安全问题,那为什么又要跨域呢? 有时公司内部有多个不同的子域,比如一个是location.company.com ,而应用是放在app.company.com , 这时想从 app.company.com去访问 location.company.com 的资源就属于跨域。
五实现跨域需要的技术手段?
1、JSONP
2、CORS:原名是跨域资源共享(Cros-origin resource sharing)
六、Nginx中跨域请求简单配置及参数详解
# Access-Control-Allow-Origin
服务器默认是不被允许跨域的。给Nginx服务器配置`Access-Control-Allow-Origin *`后,
表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。也可以指定一个确定的URL。
# Access-Control-Allow-Methods
Access-Control-Allow-Methods 是为了防止出现以下错误:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
# Access-Control-Allow-Credentials 'true’;
可选字段, 为true表示允许发送Cookie. 同时, 发送时, 必须设置XMLHttpRequest.withCredentials为true才有效. 请求若服务器不允许浏览器发送, 删除该字段即可。
# Access-Control-Allow-Headers
Access-Control-Allow-Headers 是为了防止出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
这个错误表示当前请求Content-Type的值不被支持。
其实这是我们发起了"application/json"的类型请求导致的。
这里涉及到一个概念:预检请求(preflight request)。
# 给OPTIONS 添加 204的返回
这是为了处理在发送POST请求时Nginx依然拒绝访问的错误
发送"预检请求"时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
==================================================================================
upstream apptest.com {
server 192.168.1.22:8087 max_fails=100 fail_timeout=1s;
keepalive 50000;
}
server {
listen 80;
server_name app.test.com;
access_log logs/apptest.access.log main;
error_log logs/apptest.error.log;
location / {
add_header Access-Control-Allow-Origin 'http://127.0.0.1:8080' always;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
add_header Access-Control-Allow-Credentials 'true';
add_header Access-Control-Allow-Headers 'Accept,cercode,Authorization,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://127.0.0.1:8080' always;
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'cercode,Accept, Authorization,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://apptest.com;
include proxy.conf;
}
}
==================================================================================
七、预检请求
# 简单的跨域请求可以省略预检请求的配置,非简单的跨域请求需要配置预检请求。
# 预检请求使用的过程大致如下:
1、浏览器发送请求询问当前域名是否支持跨域, 能使用哪些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…
OPTIONS表示这个请求是询问的, origin表示预检请求来自哪个源
Access-Control-Request-Method: 该字段必须, 列出浏览器的CORS请求会用到哪些HTTP方法
Access-Control-Request-Headers: 该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header。这个字段通常在XMLHttpRequest.setRequestHeader()方法中已经设置好了。
2、预检请求的回应
服务器收到预检请求后, 会检查预检请求的字段是否符合服务器的垮源规定.
若允许垮源, 则做出回应, 服务器会发送一个包含Access-Control-Allow-Origin字段的响应报文给浏览器,
例如:
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:该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次“预检”请求。
Access-Control-Allow-Headers: 如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在“预检”中请求的字段。
Access-Control-Max-Age: 该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。
=================================================
声明:本文参考了多个大佬的博客,参考链接如下,如需转载请附上以下原文连接
https://blog.csdn.net/helloyongwei/article/details/80296977
https://segmentfault.com/a/1190000012550346
https://www.cnblogs.com/happyflyingpig/p/8118818.html
http://www.ruanyifeng.com/blog/2016/04/cors.html,跨资源共享CROS详解
http://blog.csdn.net/notechsolution/article/details/50394391,跨域与跨域访问
https://www.cnblogs.com/wwlhome/p/5787133.html,$.ajax应用之请求头headers
http://www.qdfuns.com/notes/17001/6df913ad0788f32e6908d70c849b7b8e.html,如何获取跨域请求的自定义response headers
=================================================