教你搞懂什麼是跨域,如何解決跨域?

跨域:

一個域名下的網站向另外一個域名下的網站請求資源(靜態文件)css

好比: 引用別的網站的css link 標籤 引入別的網站的js 文件,可是 瀏覽器有同源策略.有的人會問? 同源策略是啥?html

同源策略:

所謂同源(即指在同一個域)就是兩個頁面具備相同的協議(protocol),主機(host)和端口號(port)前端

瀏覽器規定ajax請求只能使用來自於本身網站的數據,不容許使用本身網站之外的數據。
(1). 瀏覽器容許ajax向其它網站發送請求
(2). 瀏覽器也容許ajax接收其它網站的響應
(3). 可是瀏覽器會檢查響應數據的來源(origin):
a. 若是數據來源的服務器地址和當前網頁所在的地址相同,才能使用數據
b. 若是數據來源的服務器地址和當前網頁所在的地址不一樣,就不容許使用數據 -----同源策略 (cross orgin resoures shareing)node

跨域的幾種類型:

下面這些狀況都屬於跨域,請牢記.jquery

(1). http://www.a.com  ->  http://www.b.com  **域名不一樣**
(2). http://oa.tedu.com  ->  http://hr.tedu.com **子域名不一樣**
(3). http://localhost:3000 -> http://localhost:8080  **端口號不一樣**
(4). http://12306.cn    ->  https://12306.cn    **協議不一樣**

 

 

特別提示: 若是你是在一臺電腦上進行跨域測試的話 localhost 和127.0.0.1 這就能夠實現跨域操做了.ajax

跨域怎麼解決?

1.若是你的後端是node.js 開發的話 安裝expres中間件cors
(1). 項目本地安裝cors模塊: npm i -save cors
(2)npm

app.use(cors({
              origin:['http://localhost:8080', "http://127.0.0.1:5500"],
              credentials:true
        }))

 

2.服務端CORS跨域: 讓服務器端在返回數據前,修改響應頭中的來源json

地址與前端服務器地址同樣。
服務端接口返回數據時,不要用res.send(result) 由於 res.send()裏面封裝好了瀏覽器的源頭.
應該:後端

  res.writeHead(200,{
          "Access-Control-Allow-Origin":"http://127.0.0.1:5500" //和前端項目所在服務器的地址保持一致
        });
        res.write(JSON.stringify(result));
        res.end();

 

 

不過這個方法的缺點就是你每一個路由都要修改響應頭信息.跨域

3.jsonp

Jsonp(JSON with Padding) 是 json 的一種"使用模式",可讓網頁從別的域名(網站)那獲取資料,即跨域讀取數據。
既然ajax不能夠發起跨域請求 可是標籤能夠 script的屬性 src="" 能夠實現跨域的請求 可是咱們如何 把這個數據接收到呢?
首先看下服務器端的代碼 ,我用的是node.js 中http 模塊 和url 模塊

const http=require("http");
// 引入bodyparse 中間件
const url=require("url")
// 建立服務器
http.createServer((req,res)=>{
        var weather="北京 晴 4-24"
        res.writeHead(200,{
            "Content-Type":"text/plain; charset=utf-8"
        })
        // jqery 用callback
       
        var fname=url.parse(req.url,true).query.callback
        var stmt =`${fname}("${weather}")`
        res.write(stmt)
        res.end()
 }).listen(8080)
//  解析url  對象

 

 

瀏覽器代碼 要用到jquery 將數據類型改成"jsonp" 你會發現已經實現了跨域請求.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="jquery-1.11.3.js"></script>
</head>
<body>
    <button>今日天氣</button>
   

   
    //  <!-- <script src="http://localhost:8080?fname=show"></script> -->
</body>
 <script>
         $("button").click(function(){
        //    $(`  <script src="http://localhost:8080?fname=show">`)
        //       .appendTo("body")
           $.ajax({
              url:"http://localhost:8080",
              type:"get",
              dataType:"jsonp",
              success:function(result){
                 console.log(result)
              }    })
        })
 
        // function show(data){
        //      alert(data)
            
        //    } 
    </script>
</html>

 

不少人都很好奇,$ajax()不是不能夠跨域? 若是你只看表面那就錯了,
接下來和你們探討下底層原理.

****首先ajax是絕對不能進行跨域,爲啥 jquery 實現了呢, 那是jquery dataType:"jsonp"的 裏面封裝的是這樣的一個函數這就是原理.

$(`  <script src="http://localhost:8080?fname=show">`)
             .appendTo("body")
             //在頁面建立一個函數 這個函數的做用 對應的是
           
             function show(data){
             $("body>script:last").remove()
            alert(data)
            
        }

 

這句話啥意思呢就是,點擊按鈕建立一個script 並加到body 標籤的最後,並在全局下建立一個函數 這個函數的做用呢:

         **// 服務端 返回的其實一個函數調用語句 show()**
             調用以後,並刪除<script>標籤.
      
      點擊按鈕 調用函數 ,調用完script 標籤 並刪除他,防止頁面中多餘的script 的標籤.
相關文章
相關標籤/搜索