设为首页 收藏本站
查看: 977|回复: 0

[经验分享] Nginx跨域访问问题总结

[复制链接]

尚未签到

发表于 2018-11-8 10:58:55 | 显示全部楼层 |阅读模式
  一、什么是跨域
  简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。
  同源是指相同的协议、域名、端口。特别注意两点:
  如果是协议和端口造成的跨域问题“前台”是无能为力的,
  在跨域问题上,域仅仅是通过“协议+域名+端口”来识别,两个不同的域名即便指向同一个ip地址,也是跨域的。
  二、常见跨域情况
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服务,那么添加如下信息即可。
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代表匹配一个之后停止匹配。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-632328-1-1.html 上篇帖子: Nginx+mysql+php-fpm搭建高性能Nginx平台 下篇帖子: nginx(一)初步安装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表