跨域????如何解决

1.什么是跨域

    当一个请求url的协议、域名、端口三者之间任意一个与当前的url不同即为跨域
    ex:
        http//www....  和https//www....就是协议上的跨域(http/https)
        www.baidu.com 和www.test.com  就是主域名不同(baidu/test)
        www.test.com  和blog.test.com 就是子域名不同(WWW/blog)
        www.test.com:8080 和www.test.com:7000 端口上的跨域(8080/7000)

2.为什么浏览器会禁止跨域

    因为跨域的访问会带来许多安全性上的问题,cookie一般都用于状态控制,存储登录的信息,如果允许跨域,那么别的网站用一段脚本就可以轻松获取你的cookie数据,并且冒充身份去登录网站(这不一下就被盗号了吗),存在极大的安全隐患,所以,现在的浏览器都采用同源策略

3.非同源限制

1.无法读取非同源网页的Cookie、Localstorage和indexedDB
2.无法接触非同源网页的DOM节点
3.无法向非同源地址发送ajax请求
    注:有三个标签允许跨域加载资源
        1.<img src='xxx'>
        2.<link href='xxx'>
        3.<script src='xxx'>

4.如何解决跨域访问问题

1.document.domain
    两个页面可以通过设置相同的document.domain,因为浏览器是通过document.domain属性来检查两个网页是否同源
    使用:两个网页都设置document.domain='test.com'  #不是固定的,自己想名字噢
    缺点:这方式的局限性比较大,因为只能用于二级域名相同的情况下,比如说,a.test.com 和 b.test.com 适用该方式
2.JSONP
    利用<script>元素的开放策略,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
    与ajax的区别:
        JSONP和ajax相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但ajax属于同源策略,JSONP属于非同源策略(跨域请求)
    优点:兼容性好
    缺点:只支持get,不支持post
    使用:
        1.声明一个回调函数,其函数名(如fn)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。
        2.创建一个<script>标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=fn)。
        3.服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是fn,它准备好的数据是fn([{"name":"jianshu"}])。
        4.最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(fn),对返回的数据进行操作。
        <script type="text/javascript"src="http://crossdomain.com/jsonServerResponse?jsonp=fn">         </script>
        <script type="text/javascript">
            function fn(data){
                //处理获得的数据
            }
        </script>
    其中 fn 是客户端注册的回调的函数,目的获取跨域服务器上的json数据后,对数据进行在处理。
最后服务器返回给客户端数据的格式为:
    fn({ msg:'this  is  json  data'})
3.CORS
    CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。整个CORS通信过程都是浏览器自动完成的,不需要用户参与,浏览器一旦发现AJAX请求跨源,会自动添加一些附加的头信息,有时还会多出一次附加的请求,用户不会有感觉,因此,实现CORS通信的关键是服务器,只要服务器实现了CORS接口,就可以跨源通信
    优点:功能更加强大支持各种HTTP Method
    缺点:兼容性不如JSONP
    使用:
1.前端代码(需要判断浏览器是否支持情况)

    function createCORSRequest(method, url) {var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    // 此时即支持CORS的情况
    // 检查XMLHttpRequest对象是否有“withCredentials”属性
    // “withCredentials”仅存在于XMLHTTPRequest2对象里
    xhr.open(method, url, true);
  } else if (typeof!= "undefined") {
    // 否则检查是否支持XDomainRequest,IE8和IE9支持
    // XDomainRequest仅存在于IE中,是IE用于支持CORS请求的方式
    xhr = new XDomainRequest();
    xhr.open(method, url);
  } else {
    // 否则,浏览器不支持CORS
    xhr = null;
 
  }
  return xhr;
}
 
var xhr = createCORSRequest('GET', url);
if (!xhr) {
  throw new Error('CORS not supported');
}

服务器:
    Apache需要使用mod_headers模块来激活HTTP头的设置,它默认是激活的。你只需要在Apache配置文件的<Directory>, <Location>, <Files>或<VirtualHost>的配置里加入以下内容即可
    Header set Access-Control-Allow-Origin *
4.跨文档通信 API:window.postMessage()
    调用postMessage方法实现父窗口http://test1.com向子窗口http://test2.com发消息(子窗口同样可以通过该方法发送消息给父窗口)
    // 父窗口打开一个子窗口
var openWindow = window.open('http://test2.com', 'title');
 
    // 父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的url)
openWindow.postMessage('Nice to meet you!', 'http://test2.com');
    
// 监听 message 消息
window.addEventListener('message', function (e) {
  console.log(e.source); // e.source 发送消息的窗口
  console.log(e.origin); // e.origin 消息发向的网址
  console.log(e.data);   // e.data   发送的消息
},false);
5.WebSocket
    Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据。同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。

原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。

1.前端代码
    <div>user input:<input type="text"></div>
<script src="./socket.io.js"></script>
<script> var socket = io('http://www.domain2.com:8080'); // 连接成功处理 
socket.on('connect', function () {
    // 监听服务端消息    
    socket.on('message', function (msg) {
        console.log('data from server: ---> ' + msg);
    });
// 监听服务端关闭     
    socket.on('disconnect', function () {
        console.log('Server socket has closed.');
    });
});
document.getElementsByTagName('input')[0].onblur = function () {
    socket.send(this.value);
}; </script>

2.Nodejs socket后台:
var http = require('http');
var socket = require('socket.io');
// 启http服务
var server = http.createServer(function (req, res) {
    res.writeHead(200, {'Content-type': 'text/html'});
    res.end();
});
server.listen('8080');
console.log('Server is running at port 8080...');
// 监听socket连接 
socket.listen(server).on('connection', function (client) {
    // 接收信息     
    client.on('message', function (msg) {
        client.send('hello:' + msg);
        console.log('data from client: ---> ' + msg);
    });
// 断开处理     
    client.on('disconnect', function () {
        console.log('Client socket has closed.');
    });
});

猜你喜欢

转载自www.cnblogs.com/Mr-bear/p/11116695.html