美文网首页
跨域问题

跨域问题

作者: 春饼sama | 来源:发表于2018-10-14 19:01 被阅读0次

同源策略

浏览器出于安全策略的考虑,只允许与本域下的接口交互。
本域指:

  • 同协议
  • 同域名
  • 同端口

跨域的几种方式

1. JSONP

原理:利用html中script标签的src请求可以跨域获取资源,通过前端传递回调函数,后端用回调函数包裹数据并返回给前端,最后再由前端调用函数获取数据。

代码示例

// 前端
<script>
    var script = document.createElement('script');
    script.src = 'http://127.0.0.1:8080/JSONP?callback=_callback';
    document.body.appendChild(script);
    document.body.removeChild(script)
    // 回调函数
    var _callback = function (obj) {
        for (key in obj) { c
            onsole.log('key: ' + key + ' value: ' + obj[key]); 
        }
    }
</script>

//后端
var express = require('express')
var app = express()
const port = '8080'

app.get('/JSONP',(req,res,next) => {
    let callback = req.query.callback
    let obj ={
        type:'jsonp',
        name:'lee'
    }
    res.writeHead(200,{"Content-Type": "text/javascript"});
    res.end(`${callback}(${JSON.stringify(obj)})`)
})

app.listen(port)
console.log(`服务器地址为: http://localhost:${port}`);

JSONP跨域需要后端有对应接口

2. CORS

介绍:跨域资源共享是一种当前域的资源被其他域访问的机制
原理:当使用 XMLHttpRequest 发送请求时,浏览器如果发现违反了同源策略就会自动加上一个请求头 origin,后端在接受到请求后确定响应后会在 Response Headers 中加入一个属性 Access-Control-Allow-Origin,值就是发起请求的源地址,浏览器得到响应会进行判断 Access-Control-Allow-Origin 的值是否和当前的地址相同,只有匹配成功后才可以拿到相应数据

通过Hostbuddy修改

127.0.0.1 a.com

启动http-server,打开http://a.com:8081/CORS.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>cros</title>
</head>
<body>
</body>
<script>
    let xhr = new XMLHttpRequest()
    xhr.open('GET','http://a.com:8080/CROS',true)
    xhr.send()
    xhr.onload= function(){
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
</script>
</html>

而服务器启动在来8080端口

app.get('/CROS',(req,res) => {
    console.log('CROS');
    let obj = {
        type:'cros',
        name:'lee'
    }
    res.writeHead(200,{
        "Content-Type":"text/html;charset=UTF-8",
        "Access-Control-Allow-Origin":'http://a.com:8081' 
        //"Access-Control-Allow-Origin":'http://127.0.0.1:8081'  
       // "Access-Control-Allow-Origin":'http://b.com:8081'   
    })
    res.end(JSON.stringify(obj))
})

只有http://a.com:8081成功了,"Access-Control-Allow-Origin":*
查看浏览器origin

Request Header中
Origin: http://a.com:8081
与
Response Header中的
Access-Control-Allow-Origin: http://a.com:8081
一致

3. 降域

使用

例子:
  http://a.lcb.com:8080/a.html
  http://b.lcb.com:8080/b.html

父域名相同,只要使用

document.domain = 'lcb.com'

指定到父域,即可实现跨域

4. messagePost

父窗口

// http://a.com:8081/postMessage.html
 <!-- 通过 iframe 嵌入子页面 -->
    <iframe src="http://a.com:8082/other-domain.html"
                id="otherPage"></iframe> 
    <br/><br/> 
    <input type="text" id="message"><input type="button"
            value="Send to child.com" onclick="sendIt()" /> 

<script type="text/JavaScript">
    function sendIt(){ 
        // 通过 postMessage 向子窗口发送数据
        document.getElementById("otherPage").contentWindow 
            .postMessage( 
                document.getElementById("message").value, 
               "http://a.com:8082"
            ); 
    } 
</script>

子窗口

// http://a.com:8082/other-domain.html
<body> 
    Web page from http://localhost:8082
    <div id="content"></div> 
</body> 
<script type="text/JavaScript">
    //event 参数中有 data 属性,就是父窗口发送过来的数据
    window.addEventListener("message", function( event ) { 
        // 把父窗口发送过来的数据显示在子窗口中
      document.getElementById("content").innerHTML+=event.data+"<br/>"; 
    }, false ); 
</script>

相关文章

网友评论

      本文标题:跨域问题

      本文链接:https://www.haomeiwen.com/subject/hbmaaftx.html