前端跨域问题解决方式:
1.与服务端部署到同域上(正常部署)
2.CORS
同域安全策略CORS(Cross-Origin Resource Sharing)
它要求请求的服务器在响应的报头(Response Header)添加 Access-Control-Allow-Origin标签,从而允许此标签所对应域访问此服务器的资源,调用此服务器的接口。
缺陷:
默认情况下,跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证明等),通过将withCredentials属性设置为true,可以指定某个请求应该发送凭据。如果服务器接收带凭据的请求,会用下面的HTTP头部来响应:
Access-Control-Allow-Credentials: true
如果发送的是带凭据的请求,但服务器的相应中没有包含这个头部,那么浏览器就不会把相应交给JavaScript,请求就无法得到结果的数据(浏览器得到了,但是我们请求的方法得不到,因为被浏览器拦截了),因此在需要传Cookie等时,服务端的Access-Control-Allow-Origin必须配置具体的具体的域名。并且还需要设置其他的请求头:
Access-Control-Allow-Origin; //request.getHeader("Origin")||www.xxx.com
Access-Control-Allow-Methods; //POST, GET, OPTIONS, DELETE
Access-Control-Allow-Credentials;//是否支持cookie跨域
Access-Control-Allow-Headers;//x-requested-with,content-type
请求头
- Access-Control-Request-Method : 先导请求中的请求头,告诉服务器真实请求的http方法
- Access-Control-Request-Headers :先导请求中的请求头,告诉服务器真实请求的http请求头
响应头
- Access-Control-Allow-Origin :服务器允许跨域请求的origin
- Access-Control-Expose-Headers : 允许JavaScript读取的头部
- Access-Control-Allow-Credentials :是否允许携带cookie
- Access-Control-Allow-Methods :允许的请求方法
- Access-Control-Allow-Headers :允许的请求头部
配置
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
3. jsonp方式
4.代理服务器方式
自己写一个php,或者Java的服务端 将web项目与此项目发布到服务器,这样web项目就能直接调用此服务器的内容,然后再用此服务器调用目标服务器的内容,因为避开了浏览器的限制,因此这种方式也是能成的,但是需要注意,这种情况下因为Cookie有path和 domain的限制,因此需要截取目标服务器的Cookie,将其改为代理服务器的path和domain,否则在需要使用到Cookie的时候,由于path或domain不对,不能将Cookie转发到目标服务器。
server {
listen 80;
server_name localhost;
location / {
root /Users/Shadow/Sites;
}
error_page 500 502 503 504 /50x.html;
#relative path
location = /50x.html {
root html;
}
#absolute path
location /douban/{
proxy_pass https://www.jianshu.com/;
proxy_cookie_path / /jianshu;
}
}
那么前端ajax时,访问的域名地址是本服务器的地址,比如:
http://localhost/jianshu/index.php?r=test
它包含“jianshu”,因而会跳转到:
https://m.jianshu.com/index.php?r=test