【JavaScript】通過封裝自己的JSONP解決瀏覽器的跨域問題(Ajax跨域)

向善的燈發表於2018-09-14
版權宣告:本文為博主原創文章,未經博主允許不得轉載。更多學習資料請訪問我愛科技論壇:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/82701029
問題引出:要傳送Ajax請求,就必須使用HTTP請求?什麼是跨域問題?

什麼是跨域問題:如果兩個頁面中的協議、域名、埠、子域名任意有一項不同,兩者之間所進行的訪問行動就是跨域的,而瀏覽器為了安全問題一般都限制了跨域訪問,也就是不允許跨域請求資源。

如何解決呢?

1. 使用建立DOM元素的方式建立img物件, audio, video, link 這幾個物件都支援跨域請求,。
var img = new Image();
    img.src = `http://192.168.1.105:8080?name=zhangsan&age=18`;

類似於上面的這種呢?還有其他一些類似的標籤,實際上是可以向伺服器傳送請求的,但是不能拿到返回值

 

2.  使用link標籤, 但是也不能拿到伺服器的請求, 然後再試試script這個標籤來試試看???

<link rel="stylesheet" href="">

link標籤只能支援css的格式,其他格式的內容瀏覽器是顯示不出來的

 

3. 使用script標籤來實現跨域, 也能滿足傳送資料的要求, 接受資料呢?來測試一下。

 var script = document.createElement(`script`);
    script.src = `http://192.168.1.105:8080?name=zhangsan&age=18`;
    document.body.appendChild(script);          // 開始正式傳送請求

經測試,還是真可以的,而且在客戶端也成功接受到了資料,這說明我們終於找對了路!

 

4. 解決沒有載入完成就輸出的問題( 這樣就會等待到script標籤載入完成之後執行)

 // 在返回資料到客戶端之前,先進行字串拼接
    let json = JSON.stringify({
        id: 1,
        name: `zhangsan`,
        age: 18,
        gender: `Male`
    });

    let jsonStr = `var data = ` + json;

上面的是我們伺服器的資料, 我們直接通過字串拼接json,然後發給瀏覽器。

console.log(data)

直接輸出,我們發現報錯了,找不到這個變數???

原因是因為,瀏覽器自上而下執行程式碼,如果DOM元素沒有載入完畢就輸出,坑定會報錯的 

 

5.解決沒有載入完成就輸出的問題( 這樣就會等待到script標籤載入完成之後執行)
script.addEventListener(`load`, function () {
        console.log(data);
    });

直接繫結個事件不就行了,測試以後還真是可以。

但是,缺點是: 這種方式需要伺服器端定義一個全域性變數, 從而會汙染全域性變數, 不太推薦…………

 

 6. 上面的思路邏輯和程式碼優化, 由於指令碼執行過後才可以拿到資料, 上面的程式碼可以優化嗎?
var script = document.createElement(`script`);
    script.src = `http://192.168.1.105:8080?name=zhangsan&age=18`;
    document.body.appendChild(script);

    function callback(data) {
        console.log(data)
    }

    實現原理: 伺服器端實際上是返回了一個callback函式的呼叫, 類似於callback(jsondata), 因此當且僅當伺服器斷點資料返回來以後, 下面的這個函式就相當於是自動呼叫了, 就會直接得到伺服器端傳回來的資料資訊, 從而列印輸出資料。

伺服器端就是這樣的:

    let jsonFunc = `callback(${json})`;

7. 程式碼的繼續優化, 可以直接在請求中, 我要自己定義一個函式呢?函式名我要自己指定的方法, 可以直接寫在url請求中。

 var script1 = document.createElement(`script`);
    var url =  `http://192.168.1.105:8080?name=zhangsan&age=19&callback=callback1`;
    script1.src = url;
    document.body.appendChild(script1);
    function callback1(data) {
        console.log(data);
    }

伺服器端進行引數解析,換成使用者自己定義的函式名字不就行了?

 let callback = urlObj.query.callback;

let jsonFunc = ``+callback+`` + `(`+ json + `)`;

到此,瀏覽器的跨域問題已經基本全部解決。


相關文章