跨域的理解和解决办法

一、跨域是什么?
跨域,指的是浏览器不能执行其他网站的脚本
当前页面的url 与 请求url的协议域名端口三个其中任意一个不同时都会产生跨域。

当前url请求的url是否跨域跨域原因
https://www.baidu.comhttps://www.baidu.com/a.js同源
https://www.baidu.comhttp://www.baidu.com/a.js协议不同,一个是https,一个是http
https://www.baidu.comhttps://www.baidu.com:8080/a.js端口号不同
https://www.baidu.comhttps://www.test.com/a.js域名不同

二、为什么会有跨域
由于浏览器的同源策略限制。同源策略是一种约定,它是浏览器最核心和最基本的安全功能。web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的js脚本和另一个域的脚本进行交互。跨域限制访问,其实是浏览器的限制。

三、不同源的限制

  1. 无法读取不同源网页的cookie、localstorage、indexedDB
  2. 无法接触不同源网页的DOM
  3. 无法像不同源地址发送请求

四、前端开发常见跨域场景
前端开发过程中,在开发模式时,项目启动地址 和 部署在服务器上的数据接口地址 不同源,就会产生跨域,就会请求不到数据。

五、怎么解决跨域问题?

  1. DOM层面和数据层面
    1.1 设置document.domain解决无法读取非同源网页的 Cookie问题
    document.domain是存放文档的服务器的主机名, 因为浏览器是通过document.domain属性来检查两个页面是否同源,因此只要 通过设置相同的document.domain,两个页面就可以共享Cookie(此方案仅限主域相同,子域不同的跨域应用场景。)

    // 两个页面都设置
    document.domain = 'test.com';
    

    1.2 跨文档通信 API:window.postMessage()
    window.postMessage是HTML5新增的跨文档通信API,该API,允许跨窗口通信,不论这两个窗口是否同源。

    适合以下需求:
    
     - 页面和其打开的新窗口间数据传递
     - 多窗口间消息传递
     - 页面与嵌套的iframe消息传递
     - 上面三个场景的跨域数据传递
    
    //父页面向打开的新窗口发送消息
    var openWindow = window.open('http://test.com', 'massage');
    openWindow.postMessage('Nice to meet you!', 'http://test.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);
    
    

    1.3 window.name
    浏览器窗口有window.name属性,这个属性的最大特点是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属 性,后一个网页可以读取它。如果需要实现父页面和跨域的子页面之间的通信,需要一个和父页面同源的子页面作为中介,将跨域的子页面中的信息传递过来。

    1.4 片段标识符
    通过监听url中hash的改变来实现数据的传递

    //父页面
    <div>
    	<iframe src="./childHtml.html" id="childHtmlId"></iframe>
    </div>
    
    let ifraneDom = document.getElementById('childHtmlId')
    iframeDom.src += '#父传递给子'
    
    //子页面
    window.onhashchange = function() {
       console.log(decodeURIComponent(window.location.hash));
    };
    
    
  2. 网络层面
    根据同源策略,浏览器默认是不允许XMLHttpRequest对象访问非同一站点的资源的,所以需要破解这种限制,实现跨域访问资源。目前主要采用以下几种方式。
    1.代理
    将请求代理到同源的服务器上,可以使用Nginx、Node中间件等
    2.JSONP
    JSONP借助script元素实现跨域技术,得益于script元素有这两种特点:src不受同源策略影响,能访问任何url资源;如果访问的资源包括js代码,会在下载后自动执行。
    JSONP只支持get请求,网页通过添加一个< script >标签元素,像服务器请求JSON数据,服务器接收到请求后,将数据放在指定名字的回调函数参数位置传回来

    原生
    <script src="http://website.com/getData?callback=getData"></script>
    回调函数
    <script type="text/javascript">
    	function getData(data){
         //拿到数据
        }
    </script>
    
    vueJs
    this.$http.jsonp('ttp://website.com/getData?callback=getData', {
    	params: {},
    	jsonp: 'handleCallback'
    }).then(res => {
    	//res
    )
    

    3.CORS 方式
    CORS (Cross-Origin Resource Sharing)

    1、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin
    2、带cookie跨域请求:前后端都需要进行设置
    
    前端设置: 根据xhr.withCredentials字段判断是否带有cookie
    服务端设置: 服务器端对于CORS的支持,主要是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
    

参考文章
https://blog.csdn.net/qq_38128179/article/details/84956552
https://juejin.cn/post/6981008064543457294

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JSONP(JSON with Padding)是一种跨域解决方案,它利用了 <script> 标签可以跨域请求资源的特性。使用 JSONP,可以在客户端通过动态创建 <script> 标签来请求跨域资源。 下面是使用 JSONP 的步骤: 1. 在客户端定义一个回调函数,该回调函数用于处理从服务端返回的数据。 ``` function handleData(data) { // 处理从服务端返回的数据 } ``` 2. 创建一个 <script> 标签,将服务端的 URL 作为其 src 属性值,并在 URL 后面添加一个参数名为 callback,其值为刚才定义的回调函数名。 ``` const script = document.createElement('script'); script.src = 'http://example.com/data?callback=handleData'; document.body.appendChild(script); ``` 3. 服务端返回的数据应该是一个函数调用,该函数名为刚才在 URL 中指定的回调函数名,并且该函数的参数应该是需要返回给客户端的数据。 ``` handleData({"name": "John", "age": 30}); ``` 4. 客户端会接收到从服务端返回的数据,并且该数据会作为回调函数 `handleData()` 的参数传入。 注意事项: - 服务端返回的数据必须是一个函数调用,其中函数名是客户端指定的回调函数名。 - JSONP 只支持 GET 请求。 - JSONP 存在安全风险,因为客户端无法确定服务端返回的数据是否可信,服务端也无法确定客户端是否可信。因此,如果使用 JSONP,应该保证服务端返回的数据是安全可信的。 希望以上解释能够帮助您理解 JSONP 的实现方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值