Nginx跨域访问问题总结

本文涉及的产品
.cn 域名,1个 12个月
简介:

一、什么是跨域

简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。

同源是指相同的协议、域名、端口。特别注意两点:

如果是协议和端口造成的跨域问题“前台”是无能为力的,

在跨域问题上,域仅仅是通过“协议+域名+端口”来识别,两个不同的域名即便指向同一个ip地址,也是跨域的。


二、常见跨域情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
URL                                说明                        是否允许通信
http: //www .a.com /a .js
http: //www .a.com /b .js              同一域名下                        允许
 
http: //www .a.com /lab/a .js
http: //www .a.com /script/b .js       同一域名下不同文件夹                允许
 
http: //www .a.com:8000 /a .js
http: //www .a.com /b .js              同一域名,不同端口                不允许
 
http: //www .a.com /a .js
https: //www .a.com /b .js             同一域名,不同协议                不允许
 
http: //www .a.com /a .js
             域名和域名对应ip                不允许
 
http: //www .a.com /a .js
http: //script .a.com /b .js            主域相同,子域不同            不允许
 
http: //www .a.com /a .js
http: //a .com /b .js                    同一域名,不同二级域名(同上)不允许(cookie这种情况下也不允许访问)
 
http: //www .cnblogs.com /a .js
http: //www .a.com /b .js                不同域名                    不允许


特别注意两点:

第一,如果是协议和端口造成的跨域问题“前台”是无能为力的,第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。“URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。


三、跨域解决方案


有多种,大多是利用JS Hack


1、document.domain+iframe的设置

2、动态创建script

3、利用iframe和location.hash

4、window.name实现的跨域数据传输

5、使用HTML5 postMessage

6、利用flash  以上方案见http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html#m5

7、nginx反向代理 这个方法一般很少有人提及,但是他可以不用目标服务器配合,不过需要你搭建一个中转nginx服务器,用于转发请求。

8、Jquery JSONP(本质上就是动态创建script)http://www.cnblogs.com/chopper/archive/2012/03/24/2403945.html

9、跨域资源共享(CORS) 这就是我们要介绍的跨域解决方案,也是未来的跨域问题的标准解决方案


四、关于CORS


CORS: 跨域资源共享(Cross-Origin Resource Sharing)http://www.w3.org/TR/cors/

当前几乎所有的浏览器(Internet Explorer 8+, Firefox 3.5+, Safari 4+和 Chrome 3+)都可通过名为跨域资源共享(Cross-Origin Resource Sharing)的协议支持ajax跨域调用。(see: http://caniuse.com/#search=cors)

Chrome, Firefox, Opera and Safari 都使用的是 XMLHttpRequest2 对象, IE使用XDomainRequest。XMLHttpRequest2的Request属性:open()、setRequestHeader()、timeout、withCredentials、upload、send()、send()、abort()。

XMLHttpRequest2的Response属性:status、statusText、getResponseHeader()、getAllResponseHeaders()、entity、overrideMimeType()、responseType、response、responseText、responseXML。


1、启用 CORS 请求

假设您的应用已经在 example.com 上了,而您想要从 www.example2.com 提取数据。一般情况下,如果您尝试进行这种类型的 AJAX 调用,请求将会失败,而浏览器将会出现“源不匹配”的错误。利用 CORS,www.example2.com 服务端只需添加一个HTTP Response头,就可以允许来自 example.com 的请求:

Access-Control-Allow-Origin: http://example.com

Access-Control-Allow-Credentials: true(可选)

可将 Access-Control-Allow-Origin 添加到某网站下或整个域中的单个资源。要允许任何域向您提交请求,请设置如下:

Access-Control-Allow-Origin: *

Access-Control-Allow-Credentials: true(可选)

其实,该网站 (html5rocks.com) 已在其所有网页上均启用了 CORS。启用开发人员工具后,您就会在我们的响应中看到 Access-Control-Allow-Origin 了。


2、CORS方法实现跨域请求

要实现CORS跨域,服务端需要这个一个流程:http://www.html5rocks.com/static/images/cors_server_flowchart.png

对于简单请求,如GET,只需要在HTTP Response后添加Access-Control-Allow-Origin。

对于非简单请求,比如POST、PUT、DELETE等,浏览器会分两次应答。第一次preflight(method: OPTIONS),主要验证来源是否合法,并返回允许的Header等。第二次才是真正的HTTP应答。所以服务器必须处理OPTIONS应答。

http://enable-cors.org/server_nginx.html 这里是一个nginx启用COSR的参考配置。


流程如下:

首先查看http头部有无origin字段;

如果没有,或者不允许,直接当成普通请求处理,结束;

如果有并且是允许的,那么再看是否是preflight(method=OPTIONS);

如果是preflight,就返回Allow-Headers、Allow-Methods等,内容为空;

如果不是preflight,就返回Allow-Origin、Allow-Credentials等,并返回正常内容。

首先,在远端需要访问的主机上做设置,假如远端主机是nginx服务,那么添加如下信息即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name tangxiaoyue.com;
if  ( $http_user_agent =  "Mozilla/5.0" ){
return  403;
}
location / {
add_header  'Access-Control-Allow-Origin'  '*' ;
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' ;
后面省略。。。
}
}


五、nginx反向代理解决跨域


    禁止跨域问题其实是浏览器的一种安全行为,而现在的大多数解决方案都是用标签可以跨域访问的这个漏洞或者是技巧去完成,但都少不了目标服务器做相应的改变,如果目标服务器无法改变的时候,就需要本地服务器实现,本地实现的话,需要搭建一个nginx并把相应代码部署在它的下面,由页面请求本域名的一个地址,转由nginx代理到目标服务器处理后返回结果给页面,而且这一切都是同步的。

假如代理服务器地址是 www.c.com/proxy/html/api/msg?method=1=2;   www.c.com是nginx主机地址

远端服务器地址:http://www.b.com/api/msg?method=1=2

在nginx服务器上做如下配置

在location下面再添加一个location。

location ^~/proxy/html/{

rewrite ^/proxy/html/(.*)$ /$1 break;

proxy_pass http://www.b.com/;

}


以下做一个解释:

1.'^~ /proxy/html/ ‘

  就像上面说的一样是一个匹配规则,用于拦截请求,匹配任何以 /proxy/html/开头的地址,匹配符合以后,停止往下搜索正则。

2.rewrite ^/proxy/html/(.*)$ /$1 break;

  代表重写拦截进来的请求,并且只能对域名后边的除去传递的参数外的字符串起作用,例如www.c.com/proxy/html/api/msg?method=1=2重写。只对/proxy/html/api/msg重写。

  rewrite后面的参数是一个简单的正则 ^/proxy/html/(.*)$ ,$1代表正则中的第一个(),$2代表第二个()的值,以此类推。

  break代表匹配一个之后停止匹配。














本文转自南非蚂蚁51CTO博客,原文链接: http://blog.51cto.com/ixdba/1928719,如需转载请自行联系原作者


相关文章
|
9天前
|
Web App开发 算法 应用服务中间件
nginx开启局域网https访问
【10月更文挑战第22天】为了调试WebRTC功能,需要在局域网内搭建HTTPS协议。具体步骤包括:在已部署Nginx和安装OpenSSL的环境中生成私钥、证书签名请求和自签名证书;将生成的文件放置到Nginx的证书目录并修改Nginx配置文件,最后重启Nginx服务。注意,自签名证书不受第三方机构认可,如需正式使用,需向CA申请签名。
|
1月前
|
缓存 前端开发 应用服务中间件
CORS跨域+Nginx配置、Apache配置
CORS跨域+Nginx配置、Apache配置
121 7
|
1月前
|
应用服务中间件 Shell PHP
windows系统配置nginx环境运行pbootcms访问首页直接404的问题
windows系统配置nginx环境运行pbootcms访问首页直接404的问题
|
3月前
|
应用服务中间件 nginx Docker
本地通过域名访问虚拟机上nginx的服务、搭建域名访问环境一(反向代理配置)
这篇文章介绍了如何通过域名在本地访问虚拟机上的nginx服务,包括创建nginx容器、修改配置文件、修改本地host文件以及进行访问测试的详细步骤。文章提供了具体的Docker命令来创建并配置nginx容器,展示了配置文件的修改示例,说明了如何在本地系统的hosts文件中添加虚拟机IP和自定义域名,以及如何通过浏览器进行测试访问。
本地通过域名访问虚拟机上nginx的服务、搭建域名访问环境一(反向代理配置)
|
2月前
|
Ubuntu 应用服务中间件 数据库
Nginx配置:阻止非国内IP地址访问的设置方法
此外,出于用户隐私和法律合规性的考虑,应慎重考虑阻止特定国家或地区IP地址的决策。在某些情况下,这可能被视为歧视性或违反当地法律。
142 2
|
3月前
|
JavaScript 应用服务中间件 PHP
nginx server 禁止特定目录下的某类文件访问
【8月更文挑战第26天】这段Nginx配置代码旨在保护`/uploads/`目录下的文件,禁止执行任何`.php`, `.html`, `.htm`, 或 `.js`等潜在有害文件,即便被访问也无法运行。取而代之的是重定向到首页。为了实现这一设置,用户需要定位到对应子域名的`.conf`配置文件中进行相应修改。若网站支持多个访问域名,则需确保在正确的`.conf`文件中实施此配置。
93 1
|
3月前
|
应用服务中间件 Linux nginx
在Linux中,如何统计ip访问情况?分析 nginx 访问日志?如何找出访问页面数量在前十位的ip?
在Linux中,如何统计ip访问情况?分析 nginx 访问日志?如何找出访问页面数量在前十位的ip?
|
3月前
|
缓存 安全 应用服务中间件
Nginx:关于实现跨域代理
Nginx:关于实现跨域代理
531 1
|
4月前
|
存储 缓存 前端开发
(三)Nginx一网打尽:动静分离、压缩、缓存、黑白名单、跨域、高可用、性能优化...想要的这都有!
早期的业务都是基于单体节点部署,由于前期访问流量不大,因此单体结构也可满足需求,但随着业务增长,流量也越来越大,那么最终单台服务器受到的访问压力也会逐步增高。时间一长,单台服务器性能无法跟上业务增长,就会造成线上频繁宕机的现象发生,最终导致系统瘫痪无法继续处理用户的请求。
135 1
|
4月前
|
JavaScript 应用服务中间件 nginx
【项目部署系列教程】5. nginx配置反向代理,解决跨域接口的访问
【项目部署系列教程】5. nginx配置反向代理,解决跨域接口的访问
200 10