跨域ajax原理,跨域 ajax 请求之 cors 原理解析

9ac5e4e30859fb63569e5fad0d8d2230.png本博客不欢迎:各种镜像采集行为,请尊重知识产权法律法规。大家都是程序员,不要闹得不开心。

本文是系列文章,上一篇文章地址是:https://newsn.net/say/cross-domain-ajax-jsonp.html 。本文主要说两个高级点的跨域话题,即:接口cookie传递及不使用jsonp如何设置跨域。

027da9c3094e01e16b420e23ab64f62a.png跨域 ajax 请求之 cors 原理解析(图1-1)

原理描述

目前的最新浏览器下面,都可以不使用jsonp来跨域了,就是说还使用传统的json。当然了,前端请求的时候,要特殊写上点代码,后端处理的时候,也需要发出特殊的header头,整个过程才能畅通。

另外,默认情况下,跨域的话,是不会发送cookie的。而服务器端接口需要做权限判断之类的话,就需要cookie上的支持。这个时候,同样需要做些设置。

前端代码

好了,先整体的来说。下面是前端相关代码,以jquery为例:$.ajaxSetup({

crossDomain: true,

xhrFields: {

withCredentials: true

}

});

这个非常简单,设置上这个之后,页面上所有的ajax请求都不用特殊写代码了,都会默认支持跨域传递cookie。是不是很简单?

如果你不这么整体的来写的话,每个ajax请求都需要额外添加crossDomain和xhrFields这2个属性。貌似真心不是很方便。$.ajax({

url:'https://newsn.net/',

type:'GET',

dataType:'json',

success:function (data) {},

crossDomain: true,

xhrFields: {

withCredentials: true

}

});

后端代码

后端服务器端,需要发送这些header头到客户端,苏南大叔下面的demo是php版本的。Access-Control-Allow-Credentials:true

Access-Control-Allow-Headers:*

Access-Control-Allow-Methods:GET,POST,OPTIONS

Access-Control-Allow-Origin:*

Access-Control-Max-Age:864000

这里要特别强调的是:Access-Control-Allow-Origin这个属性,设置为*肯定可以。不过,这就非常不安全了,因为这个就是来控制到底哪个域名可以跨域访问接口的。所以,这个属性,一定要设置为具体的网址才好,注意要设置为 https://yourdomain.com:port 类似这样的,http和https一定要区分好,端口号如果有的话,也一定要带上。当然了,这些header是php发出的,还是nginx发出的,都是可以的。

nginx代替php发出特定header

可能,nginx发出header似乎更合适一些。那么下面贴出的就是可能的nginx设置。

参考文章:https://enable-cors.org/server_nginx.htmllocation / {

if ($request_method = 'OPTIONS') {

add_header 'Access-Control-Allow-Origin' '*';

#

# Om nom nom cookies

#

add_header 'Access-Control-Allow-Credentials' 'true';

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-Credentials' 'true';

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-Credentials' 'true';

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';

}

}

下面的是另外一个我使用过的配置:server {

listen 443 ssl;

server_name blogd.newsn.net;

ssl_certificate /application/nginx/ssl/newsn.net.crt;

ssl_certificate_key /application/nginx/ssl/newsn.net.key;

ssl_session_timeout 5m;

ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;

ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5;

ssl_prefer_server_ciphers on;

access_log /data/logs/nginx/cloud/access.log json;

error_log /data/logs/nginx/cloud/error.log error;

set $ACAO 'http://blog.newsn.net https://blog.newsn.net';

if ($http_origin ~* ^(http|https)://blog\.newsn\.net$) {

set $ACAO $http_origin;

}

add_header Access-Control-Max-Age 864000;

add_header Access-Control-Allow-Credentials true;

add_header Access-Control-Allow-Origin '$ACAO';

add_header Access-Control-Allow-Headers X-Requested-With;

add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

location /robots.txt {

root html;

}

location / {

if ($request_method = 'OPTIONS') {

add_header Access-Control-Max-Age 864000;

add_header Access-Control-Allow-Credentials true;

add_header Access-Control-Allow-Origin '$ACAO';

add_header Access-Control-Allow-Headers X-Requested-With;

add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

return 204;

}

proxy_pass http://blog-portal;

proxy_http_version 1.1;

proxy_set_header Connection "";

#proxy_set_header Host $host:$server_port;

proxy_set_header Host $host;

#proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#proxy_set_header X-Forwarded-Proto $scheme;

}

}

server {

listen 80;

server_name blog.newsn.net;

rewrite ^(.*) https://blog.newsn.net$1 permanent;

}

结语

苏南大叔觉得,鉴于nginx设置如此繁杂,我们还是老老实实的用php输出header吧,其实蛮简单的。是不是?据说,上述设置中的js部分在ie低版本浏览器下面是不ok的。那么如果我们需要兼容ie低版本的话,那么还是老老实实的写不安全的jsonp,似乎是更好的解决方案。

93ddba5b688a6967c0a88c0220992c34.png

e6eebe3032abd035b5cf072fe954fec6.png 如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。

9ac5e4e30859fb63569e5fad0d8d2230.png 本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值