1、为什么会出现跨域问题?
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。
2、什么是跨域?
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域,如下表格:
| **当前页面url** | **被请求页面url** | **是否跨域** | **原因** |
| http://www.abc.com/ | http://www.abc.com/index.html | 否 | 同源(协议、域名、端口号相同) |
| http://www.abc.com/ | https://www.abc.com/index.html | 跨域 | 协议不同(http/https) |
| http://www.abc.com/ | http://www.baidu.com/ | 跨域 | 主域名不同(abc/baidu) |
| http://www.abc.com/ | http://blog.abc.com/ | 跨域 | 子域名不同(www/blog) |
| http://www.abc.com:8080/ | http://www.abc.com:7001/ | 跨域 | 端口号不同(8080/7001) |
2、非同源有什么限制呢?
(1)无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB。
(2)无法接触非同源网页的 DOM。
(3)无法向非同源地址发送 AJAX 请求。
3、解决跨域方法
其实解决跨域的办法有很多,主要以下常用方法:
(1)设置document.domain解决。
(2)window.postMessage()跨文档通信API。
(4)JSONP方式。
(5)CORS,服务端程序编码设置Access-Control-Allow-Origin。
以上的方法中出于各后端语言的不同以及对浏览器兼容性是支持差异,多多少少都存在着一些瑕疵,说白了就是坑多~~~
使用Nginx的配置能简单解决这一问题,告别各种由于后端语言、浏览器兼容性等原因而不得不增加各种兼容行编码的繁琐。
具体Nginx配置关键几行代码如下:
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials: true;
add_header Access-Control-Allow-Headers 'DNT,token,app-token,Authorization,Accept,
Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,
If-Modified-Since,Cache-Control,Content-Type,Range';
if ($request_method = 'OPTIONS') {
return 204;
}
把这几行配置添加到部署后端api服务的Nginx服务器即可,如下完整的配置:
server
{
listen 80;
server_name www.xxx.com;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/www.xxx.com/web;
#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#SSL-END
#ERROR-PAGE-START 错误页配置,可以注释、删除或修改
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log off;
access_log /dev/null;
}
location ~ .*\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
}
access_log /www/wwwlogs/www.xxx.com.log; error_log /www/wwwlogs/www.xxx.com.error.log;
}
是不是很简快捷,如果觉得有用,请给个赞!