跨域問題

同源策略

瀏覽器出于安全策略的考慮,只允許與本域下的接口交互。
本域指:

  • 同協(xié)議
  • 同域名
  • 同端口

跨域的幾種方式

1. JSONP

原理:利用html中script標簽的src請求可以跨域獲取資源,通過前端傳遞回調(diào)函數(shù),后端用回調(diào)函數(shù)包裹數(shù)據(jù)并返回給前端,最后再由前端調(diào)用函數(shù)獲取數(shù)據(jù)。

代碼示例

// 前端
<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)
    // 回調(diào)函數(shù)
    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 發(fā)送請求時,瀏覽器如果發(fā)現(xiàn)違反了同源策略就會自動加上一個請求頭 origin,后端在接受到請求后確定響應后會在 Response Headers 中加入一個屬性 Access-Control-Allow-Origin,值就是發(fā)起請求的源地址,瀏覽器得到響應會進行判斷 Access-Control-Allow-Origin 的值是否和當前的地址相同,只有匹配成功后才可以拿到相應數(shù)據(jù)

通過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'

指定到父域,即可實現(xiàn)跨域

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 向子窗口發(fā)送數(shù)據(jù)
        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 參數(shù)中有 data 屬性,就是父窗口發(fā)送過來的數(shù)據(jù)
    window.addEventListener("message", function( event ) { 
        // 把父窗口發(fā)送過來的數(shù)據(jù)顯示在子窗口中
      document.getElementById("content").innerHTML+=event.data+"<br/>"; 
    }, false ); 
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容