zoukankan      html  css  js  c++  java
  • 跨域????如何解决

    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.');
        });
    });
    
  • 相关阅读:
    初探nodejs事件循环机制event loop
    夯实基础之--new关键字、instanceOf原理
    分享-结合demo讲解JS引擎工作原理
    Linux-centos安装node、nginx小记
    openlayers5实战--踩坑总结
    node+koa中转层开发实践总结
    vue预渲染实践总结
    css多行省略-webkit-box-orient打包编译后失效原因
    使用mpVue开发小程序实战总结
    Linux crontab定时执行任务
  • 原文地址:https://www.cnblogs.com/Mr-bear/p/11116695.html
Copyright © 2011-2022 走看看