javascript 跨域问题
1.同源策略起源
- 同源策略是浏览器最基本的安全策略,它认为任何站点的内容都是不安全的,所以当脚本运行时,只被允许访问来自同一站点的资源。
- 同源是指域名、协议、端口都相同。
- 如果没有同源策略,就会发生下面这样的问题:
恶意网站用一个iframe把真实的银行登录页放到他的页面上,当用户使用用户名密码登录时,父页面的javascript就可以读取到银行登录页表单中的内容。甚至浏览器的1个Tab页打开了恶意网站,另一个Tab页打开了银行网站,恶意网站中的javascript可以读取到银行网站的内容。这样银行卡和密码就能被轻易拿走。``
## 2. 跨域访问
- 由于同源策略的原因,浏览器对跨域访问做了很多限制,但有时我们的确需要做跨域访问,那要怎么办?常见的解决办法有以下几种:
#### 2-1 浏览器端解决方案> 客户端的解决方案主要有`iframe传值`和`jsonCallback`
- iframe传值 + a.com下有a.html; + a.html创建iframe加载b.com下的b.html,可在加载b.html时通过?或#将参数传递到b.html中; + b.html加载后,可以通过提取location.search或location.hash中的内容获取a.html传过来的参数; + b.html创建一个iframe,加载a.com下的c.html,并且参数也通过?或#传给c.html; + 因为c.html和a.html是相同域名,所以c.html可以使用parent.parent访问到a.html的对象,这样也就可以将b.html需要传递的参数传回到a.html中。
- jsonCallback- 客户端js代码:```js$.ajax({type : "get",async:false,url : "ajax.ashx",dataType : "jsonp",jsonp: "callbackparam",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)jsonpCallback:"success_jsonpCallback",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名success : function(json){alert(json);alert(json[0].name);},error:function(){alert('fail');}});
- 服务器端响应代码(C#):
public void ProcessRequest (HttpContext context) {context.Response.ContentType = "text/plain";string callbackFunName = context.Request["callbackparam"];context.Response.Write(callbackFunName + "([ { name:\"John\"} ] )");}
- jsonp String
在一个jsonp请求中重写回调函数的名字。这个值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,比如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。jsonpCallback String为jsonp请求指定一个回调函数名。这个值将用来取代jQuery自动生成的随机函数名。这主要用来让jQuery生成度独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存GET请求的时候,指定这个回调函数名。
ajax jsonp与普通的ajax请求的主要区别在于——请求响应结果的处理。如上面代码所示的响应结果为:success_jsonpCallback([ { name:"John"} ] ); ————其实就是,调用jsonp回调函数success_jsonpCallback,并将要响应的字符串或json传入此方法(作为参数值),其底层的实现,大概的猜想应该是:
function success_jsonpCallback(data){success(data);}
2-2 服务端解决方案
服务端解决方案也主要有两种
增加http头信息
和反向代理
- 增加http头信息
- 在服务器返回信息中增加以下头信息: Access-Control-Allow-Origin: 允许的域名 Access-Control-Allow-Methods: 允许的请求方式
-
反向代理(Reverse Proxy)是指以代理服务器来接受 Internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 Internet 请求连接的客户端,此时,代理服务器对外就表现为一个服务器。
-
正向代理(Forward Proxy),通常都被简称为代理,就是在用户无法正常访问外部资源,比方说受到GFW的影响无法访问twitter的时候,我们可以通过代理的方式,让用户绕过防火墙,从而连接到目标网络或者服务。
-
反向代理的服务器配置
# 反向代理设置nginxlocation /api { proxy_pass "http://192.168.60.31:8602"; proxy_set_header Host "192.168.60.31:8602"; proxy_set_header X-Forwarded-For $remote_addr;}
# 反向代理设置Apache<Proxy *>Order deny,allowAllow from all</Proxy>ProxyPass /api http://192.168.60.31:8602ProxyPassReverse /api http://192.168.60.31:8602