关于跨域的理解

为什么会有跨域这个问题的出现呢?

这要谈到浏览器的同源策略了,同源策略限制了不同源之间的资源进行交互,用于隔离潜在的恶意文件的安全机制,并且是浏览器最基本的安全机制(同源:协议、域名、端口均相同,localhost和127.0.0.1也属于跨域)。

如果没有同源策略的限制,假设您进入一个银行网站A,输入了账号密码进行登录,服务器端验证通过后会在响应头中添加Set-Cookie字段,在下次访问时,浏览器就会将cookie附加在http请求头字段Cookie中,服务器就知道您已经登录过,便不再验证了,如果在cookie信息还存在的情况下,您访问另一个网站B,如果它是一个恶意网站,在您不知情的情况下向网站A发起了请求,这就相当于不法网站B登录了您的账户,可以为所欲为了!

又比如一个钓鱼网站,模仿银行网站A(没有了同源策略的限制,钓鱼网站就可以很轻松的网站A的DOM),诱导您输入账户密码信息,然后就可想而知了......

那么怎么实现跨域呢?

关于解决跨域的问题,这里只记录部分实现方式:

CORS(Cross-origin resource sharing)跨域资源共享

CORS是处理跨域问题的标准做法,需要浏览器和服务器同时支持,CORS的整个通讯过程都是浏览器自动完成的,而实现通信的关键是服务器,只要服务器实现了CORS接口,就可以实现跨域通信。

CORS通信与ajax通信没有什么差别,浏览器一旦发现ajax请求跨域,就会自动添加一些头信息。浏览器将CORS请求分为两类:简单请求,非简单请求。

对于简单请求,其请求方法必须是HEAD,PUT,GET,请求头不能超过一下5种字段:Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain。凡是不满足以上两种情况的都是非简单请求,浏览器对这两种请求的处理方式是不同的,具体详情请参考阮一峰老师的博客http://www.ruanyifeng.com/blog/2016/04/cors.html

JSONP(JSON with padding)

JSONP是JSON的一种使用模式,可以让网页从别的网站获取资料,即跨域读取资料。

与CORS相比,JSONP只支持get请求,CORS支持所有类型的http请求。

JSON是一种数据格式,而JSONP是将这种数据格式在客户端和服务器端进行传输的方式,JSONP利用具有src属性的标签(比如<script>、<img>、<iframe>)实现跨域,因为它们可以用来请求不同源的文件,JSONP通过在请求文件的url中添加请求参数和callback,可以使服务器端将请求的数据通过JSON格式传入客户端的callback指定的函数中进行处理,比如下面的代码(参考文章http://www.cnblogs.com/wjlog/p/5903238.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>

</body>
</html>

使用jQuery实现jsonp调用:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" >
 <head>
     <title>Untitled Page</title>
      <script type="text/javascript" src=jquery.min.js"></script>
      <script type="text/javascript">
     jQuery(document).ready(function(){ 
        $.ajax({
             type: "get",
             async: false,
             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
             dataType: "jsonp",
             jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
             jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
             success: function(json){//jQuery自动生成回调函数将数据传给success调用
                 alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
             },
             error: function(){
                 alert('fail');
             }
         });
     });
     </script>
     </head>
  <body>
  </body>
 </html>

jQuery将jsonp封装进了ajax,当然,ajax也可以通过服务器端设置代理实现跨域

代理

请求是使用前端的域名,通过代理(Nginx 配置),将请求转发到真正的后端的域名上。

server{

    # 监听8080端口

    listen 8080;

    # 域名是localhost

    server_name localhost;

    #只要是localhost:8080/api开头的,都转发到真正的服务端地址http://localhost:8888

    location ^~ /api {

        proxy_pass http://localhost:8888;

    }    

}

window.postMessage()

是H5的一个接口,专注实现不同窗口不同页面之间的跨域通讯

document.domain()

这种方式只适用于主域名相同,但子域名不同的iframe跨域,比如主域名http://ceshi.com:8080,子域名是 http://child.ceshi.com:8080,这时只需给两个页面指定一下document.domain = ceshi.com就可以访问各自的window对象了。

猜你喜欢

转载自blog.csdn.net/qq_36367995/article/details/81174896
今日推荐