其实很早就接触过前端开发 也处理过跨域问题(当时采用的是jsonp server+client 都要改动。。。。)
javascript
如今这段时间也在作这块 记录+整理php
一个网站的网址组成包括协议名,域名,端口号。好比 http://www.sagosoft.com,其中http是协议名,www.sagosoft.com是域名,端口号是80,当在在页面中从一个url请求数据时,若是这个url的协议名、子域名、主域名、端口号任意一个有一个不一样,就会产生跨域问题。
即便是在 http://localhost:8080/
页面请求 http://127.0.0.1:8080/
也会有跨域问题html
常见的不一样域间的页面制约dom元素包括:前端
window.location 能够设置,但不能读取。其它的 location 属性和方法被禁止访问;
document.href 能够设置,但不能读取。其它的 document 属性和方法被禁止访问;
<iframe> 的 src 能够设置,但不能读取html5
ajax访问无返回值??java
因为安全缘由,跨域访问是被各大浏览器所默认禁止的;可是浏览器并不由止在页面中引用其余域的JS文件,并能够自由执行引入的JS文件中的function
jquery
解决跨域问题有如下tri种方式nginx
使用jsonpgit
服务端代理github
服务端设置Request Header
头中Access-Control-Allow-Origin
为指定可获取数据的域名
json≠jsonp
jsonp解决跨域问题的原理是,浏览器的script
标签是不受同源策略限制(你能够在你的网页中设置script
的src
属性问cdn服务器中静态文件的路径)。那么就可使用script标签从服务器获取数据,请求时添加一个参数为callbakc=?,?号时你要执行的回调方法。
以jQuery2.1.3的ajax方法为例
$.ajax({ url:"", dataType:"jsonp", data:{ params:"" } }).done(function(data){ //dosomething..})
仅仅是客户端使用jsonp请求数据是不行的,由于jsonp的请求是放在script
标签中的,和普通请求不一样的地方在于,它请求到的是一段js代码,若是服务端返回了json字符串,那么浏览器就会报错。因此jsonp返回数据须要服务端作一些处理。
上面说了jsonp的原理是利用script
标签来解决跨域,可是script
标签是用来获取js代码的,那么咱们怎么获取到请求的数据呢。
这就须要服务端作一些判断,当参数中带有callback属性时,返回的type要为application/javascript
,把数据做为callback的参数执行。下面是jsonp返回的数据的格式示例
/* typeof jQuery21307270454438403249_1428044213638 === 'function'*/ jQuery21307270454438403249_1428044213638({"code":1,"msg":"success","data":{"test":"test"}});
这是express4.12.3关于jsonp的实现代码
if (typeof callback === 'string' && callback.length !== 0) { this.charset = 'utf-8'; this.set('X-Content-Type-Options', 'nosniff'); this.set('Content-Type', 'text/javascript'); // restrict callback charset // replace chars not allowed in JavaScript that are in JSON callback = callback.replace(/[^\[\]\w$.]/g, ''); body = body.replace(/\u2028/g, '\\u2028') .replace(/\u2029/g, '\\u2029'); // the /**/ is a specific security mitigation for "Rosetta Flash JSONP abuse" // the typeof check is just to reduce client error noise body = '/**/ typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');'; }
这种方式只要服务端把response的header头中设置Access-Control-Allow-Origin
为制定可请求当前域名下数据的域名便可。通常状况下设为便可。这样客户端就不须要使用jsonp来获取数据。
可是我的是用这个方法的
CORS支持POST提交,而且实施起来嘿简单,CORS原理:只须要向响应头header中注入Access-Control-Allow-Origin,这样浏览器检测到header中的Access-Control-Allow-Origin,则就能够跨域操做。
我用的是php,用法如:(*号也能够指定特定的域名,只容许该域名访问)
<?php header("Access-Control-Allow-Origin:*"); //...
若是是java,
response.setHeader("Access-Control-Allow-Origin", "*");
Access-Control-Allow-Origin是html5新增的一项标准,IE10如下是不支持的,因此若是产品面向的是PC端,就要使用服务端代理或jsonp。
见图
====================================================================
主要解决方案 :
jsonp (jquery-jsonp插件也可)
服务端代理(经过在同域名下的web服务器端建立一个代理,这个须要在服务器端作 服务器的负荷+++)
nginx反向代理
<script> 跨域获取资源(要求返回的是正规的js对象格式 如json、js数组)
隐藏iframe、共享domain(只适用在具备同一个父域下的跨域请求上)