版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。更多學習資料請通路我愛科技論壇: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 + ')';
到此,浏覽器的跨域問題已經基本全部解決。