柚子快報(bào)邀請(qǐng)碼778899分享:前端 Ajax的簡(jiǎn)介和使用
柚子快報(bào)邀請(qǐng)碼778899分享:前端 Ajax的簡(jiǎn)介和使用
一、Ajax簡(jiǎn)介
????????AJAX 全稱為 Asynchronous JavaScript And XML,就是異步的 JS 和 XML。
通過 AJAX 可以在瀏覽器中向服務(wù)器發(fā)送異步請(qǐng)求,最大的優(yōu)勢(shì):無刷新獲取數(shù)據(jù)。
AJAX 不是新的編程語言,而是一種將現(xiàn)有的標(biāo)準(zhǔn)組合在一起使用的新方式。
1、XML簡(jiǎn)介
XML 可擴(kuò)展標(biāo)記語言。 XML 被設(shè)計(jì)用來傳輸和存儲(chǔ)數(shù)據(jù)。 XML 和 HTML 類似,不同的是 HTML 中都是預(yù)定義標(biāo)簽,而 XML 中沒有預(yù)定義標(biāo)簽, 全都是自定義標(biāo)簽,用來表示一些數(shù)據(jù)。
比如說我有一個(gè)學(xué)生數(shù)據(jù): name = “孫悟空” ; age = 18 ; gender = “男” ;
1
2
3
4
5
6
用 XML 表示:
現(xiàn)在已經(jīng)被 JSON 取代了。
1
{"name":"孫悟空","age":18,"gender":"男"}
2、Ajax的特點(diǎn)
(1)AJAX 的優(yōu)點(diǎn)
可以無需刷新頁面而與服務(wù)器端進(jìn)行通信。 允許你根據(jù)用戶事件來更新部分頁面內(nèi)容。
(2)Ajax的缺點(diǎn)
沒有瀏覽歷史,不能回退 存在跨域問題(同源) SEO 不友好
3、HTTP簡(jiǎn)介
HTTP(hypertext transport protocol)協(xié)議『超文本傳輸協(xié)議』,協(xié)議詳細(xì)規(guī)定了瀏覽器和萬維網(wǎng)服務(wù)器之間互相通信的規(guī)則、約定,、規(guī)則
(1)請(qǐng)求報(bào)文
1
2
3
4
5
6
7
8
>行 POST /s?ie=utf-8 HTTP/1.1
/s:表示路徑 ie=utf-8:表示編碼方式的查詢參數(shù)
HTTP/1.1:表示使用的 HTTP 協(xié)議版本。 >頭 Host: atguigu.com //指定服務(wù)器的主機(jī)名或 IP 地址
>? Cookie: name=guigu //包含在此請(qǐng)求中發(fā)送到服務(wù)器的 cookie 數(shù)據(jù)
>? Content-type: application/x-www-form-urlencoded //指定請(qǐng)求體的數(shù)據(jù)類型。在這里,是表單數(shù)據(jù)的 MIME 類型。
>? User-Agent: chrome 83 //發(fā)起請(qǐng)求的客戶端瀏覽器和版本信息。
>空行
>體 username=admin&password=admin //實(shí)際要發(fā)送到服務(wù)器的數(shù)據(jù)。這里使用的是 application/x-www-form-urlencoded 格式,即鍵值對(duì)形式的表單數(shù)據(jù)
(2)響應(yīng)報(bào)文
1
2
3
4
5
6
7
8
9
10
11
12
13
>行 HTTP/1.1 200 OK
HTTP/1.1:表示使用的 HTTP 協(xié)議版本。
200 OK:表示服務(wù)器成功處理了請(qǐng)求。200是狀態(tài)碼,表示成功;OK是狀態(tài)碼的短語描述。 >頭 Content-Type: text/html;charset=utf-8 //指定了響應(yīng)體的類型為text/html,即 HTML 文檔;并且指定了字符編碼為 UTF-8,確保瀏覽器正確地解析和顯示文本內(nèi)容。
>? Content-length: 2048 //響應(yīng)體的長度為 2048 字節(jié)。瀏覽器在接收完這么多字節(jié)后會(huì)認(rèn)為響應(yīng)體已經(jīng)接收完畢。
>? Content-encoding: gzip //響應(yīng)體使用了 gzip 壓縮算法進(jìn)行了壓縮。有助于減少數(shù)據(jù)傳輸時(shí)的網(wǎng)絡(luò)帶寬消耗,提高傳輸效率
>空行
>體
>?
>?
>?
>?
尚硅谷
>?
>?
(3)Chrome網(wǎng)絡(luò)控制臺(tái)查看通信報(bào)文
1、Network –> Hearders 請(qǐng)求頭
2、Network –> Response 響應(yīng)體:通常返回的是html
二、原生Ajax
1、XMLHttpRequest,AJAX 的所有操作都是通過該對(duì)象進(jìn)行的。
2、當(dāng)前端想設(shè)置自定義的請(qǐng)求頭時(shí),需要讓后端設(shè)置響應(yīng)頭
1
2
3
//表示接收任意類型的請(qǐng)求
app.all('/server', (request, response) => {
//響應(yīng)頭 允許跨域 運(yùn)行自定義響應(yīng)頭
response.setHeader('Access-Control-Allow-Origin', '*'); response.setHeader('Access-Control-Allow-Headers', '*');}
3、ajax請(qǐng)求狀態(tài):xhr.readyState
?0:請(qǐng)求未初始化,還沒有調(diào)用 open()。
? 1:請(qǐng)求已經(jīng)建立,但是還沒有發(fā)送,還沒有調(diào)用 send()。
? 2:請(qǐng)求已發(fā)送,正在處理中(通?,F(xiàn)在可以從響應(yīng)中獲取內(nèi)容頭)。
? 3:請(qǐng)求在處理中;通常響應(yīng)中已有部分?jǐn)?shù)據(jù)可用了,沒有全部完成。
? 4:響應(yīng)已完成;您可以獲取并使用服務(wù)器的響應(yīng)了
4、Ajax的使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1) 創(chuàng)建 XMLHttpRequest 對(duì)象
var xhr = new XMLHttpRequest();
2) 設(shè)置請(qǐng)求信息
xhr.open(method, url);
//可以設(shè)置請(qǐng)求頭,一般不設(shè)置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
3) 發(fā)送請(qǐng)求
xhr.send(body) //get 請(qǐng)求不傳 body 參數(shù),只有 post 請(qǐng)求使用
4) 接收響應(yīng)
//xhr.responseXML 接收 xml 格式的響應(yīng)數(shù)據(jù)
//xhr.responseText 接收文本格式的響應(yīng)數(shù)據(jù)
xhr.onreadystatechange = function (){
if(xhr.readyState == 4 && xhr.status == 200){
var text = xhr.responseText;
console.log(text);
}}
(1)Get方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//綁定事件
btn.onclick = function () {
//1. 創(chuàng)建對(duì)象
const xhr = new XMLHttpRequest();
//2. 初始化 設(shè)置請(qǐng)求方法和 url
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
//3. 發(fā)送
xhr.send();
//4. 事件綁定 處理服務(wù)端返回的結(jié)果
// on when 當(dāng)....時(shí)候
// readystate 是 xhr 對(duì)象中的屬性, 表示狀態(tài) 0 1 2 3 4
// change 改變
xhr.onreadystatechange = function () {
//判斷 (服務(wù)端返回了所有的結(jié)果)
if (xhr.readyState === 4) {
//判斷響應(yīng)狀態(tài)碼 200 404 403 401 500
// 2xx 成功
if (xhr.status >= 200 && xhr.status < 300) {
//處理結(jié)果 行 頭 空行 體
//響應(yīng)
// console.log(xhr.status);//狀態(tài)碼
// console.log(xhr.statusText);//狀態(tài)字符串
// console.log(xhr.getAllResponseHeaders());//所有響應(yīng)頭
// console.log(xhr.response);//響應(yīng)體
//設(shè)置 result 的文本
result.innerHTML = xhr.response;
} else {}
}
}
}
(2)Post方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//綁定事件
result.addEventListener("mouseover", function(){
//1. 創(chuàng)建對(duì)象
const xhr = new XMLHttpRequest();
//2. 初始化 設(shè)置類型與 URL
xhr.open('POST', 'http://127.0.0.1:8000/server');
//設(shè)置請(qǐng)求頭
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','atguigu');
//3. 發(fā)送
xhr.send('a=100&b=200&c=300');
// xhr.send('a:100&b:200&c:300');
// xhr.send('1233211234567');
//4. 事件綁定
xhr.onreadystatechange = function(){
//判斷
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
//處理服務(wù)端返回的結(jié)果
result.innerHTML = xhr.response;
}
}
}
});
(3)解決ie緩存問題
問題:在一些瀏覽器中(IE),由于緩存機(jī)制的存在,ajax 只會(huì)發(fā)送的第一次請(qǐng)求,剩余多次請(qǐng)求不會(huì)再發(fā)送給瀏覽器而是直接加載緩存中的數(shù)據(jù)。
解決方式:瀏覽器的緩存是根據(jù) url地址來記錄的,所以我們只需要修改 url 地址 即可避免緩存問題?xhr.open("get","/testAJAX?t="+Date.now());
(4)請(qǐng)求超時(shí)與網(wǎng)絡(luò)異常
當(dāng)你的請(qǐng)求時(shí)間過長,或者無網(wǎng)絡(luò)時(shí),進(jìn)行的相應(yīng)處理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
btn.addEventListener('click', function(){
const xhr = new XMLHttpRequest();
//超時(shí)設(shè)置 2s 設(shè)置
xhr.timeout = 2000;
//超時(shí)回調(diào)
xhr.ontimeout = function(){
alert("網(wǎng)絡(luò)異常, 請(qǐng)稍后重試!!");
}
//網(wǎng)絡(luò)異?;卣{(diào)
xhr.onerror = function(){
alert("你的網(wǎng)絡(luò)似乎出了一些問題!");
}
xhr.open("GET",'http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status< 300){
result.innerHTML = xhr.response;
}
}
}
})
(5)取消請(qǐng)求
在請(qǐng)求發(fā)出去后但是未響應(yīng)完成時(shí)可以進(jìn)行取消請(qǐng)求操作
1
2
3
4
5
6
7
8
9
10
11
const btns = document.querySelectorAll('button');
let x = null;
btns[0].onclick = function(){
x = new XMLHttpRequest();
x.open("GET",'http://127.0.0.1:8000/delay');
x.send();
}
// abort
btns[1].onclick = function(){
x.abort();
}
(6)重復(fù)請(qǐng)求問題
利用之前取消請(qǐng)求知識(shí)點(diǎn),當(dāng)我點(diǎn)擊時(shí)判斷之前請(qǐng)求是否在發(fā)送中,如果是,則停止請(qǐng)求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
btns[0].onclick = function(){
//判斷標(biāo)識(shí)變量
if(isSending) x.abort();// 如果正在發(fā)送, 則取消該請(qǐng)求, 創(chuàng)建一個(gè)新的請(qǐng)求
x = new XMLHttpRequest();
//修改 標(biāo)識(shí)變量的值
isSending = true;
x.open("GET",'http://127.0.0.1:8000/delay');
x.send();
x.onreadystatechange = function(){
if(x.readyState === 4){
//修改標(biāo)識(shí)變量
isSending = false;
}
}
}
三、常見三種Ajax請(qǐng)求方式
1、jQuery發(fā)送AJAX請(qǐng)求
jQuery有三種發(fā)送請(qǐng)求方法:
當(dāng)你只是簡(jiǎn)單的請(qǐng)求數(shù)據(jù),可以直接使用前兩種方式請(qǐng)求,當(dāng)你需要設(shè)置的東西較多的時(shí)候,可以使用$.ajax()方法
(1)$.get()
1
2
3
4
5
$('button').eq(0).click(function(){
$.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
console.log(data);
},'json');
});
(2)$.post()
1
2
3
4
5
$('button').eq(1).click(function(){
$.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
console.log(data);
});
});
(3)$.ajax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$('button').eq(2).click(function(){
$.ajax({
//url
url: 'http://127.0.0.1:8000/jquery-server',
//參數(shù)
data: {a:100, b:200},
//請(qǐng)求類型
type: 'GET',
//響應(yīng)體結(jié)果
dataType: 'json',
//成功的回調(diào)
success: function(data){
console.log(data);
},
//超時(shí)時(shí)間
timeout: 2000,
//失敗的回調(diào)
error: function(){
console.log('出錯(cuò)啦!!');
},
//頭信息
headers: {
c:300,
d:400
}
});
});
2、Axios發(fā)送AJAX請(qǐng)求
(1)axios.get()
axios.get(url,data,params)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//配置 baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btns[0].onclick = function () {
//GET 請(qǐng)求
axios.get('/axios-server', {
//url 參數(shù)
params: {
id: 100,
vip: 7
},
//請(qǐng)求頭信息
headers: {
name: 'atguigu',
age: 20
}
}).then(value => {
console.log(value);
});
}
(2)axios.post()
axios.post(url,data,params)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//配置 baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btns[1].onclick = function () {
axios.post('/axios-server', {
username: 'admin',
password: 'admin'
}, {
//url
params: {
id: 200,
vip: 9
},
//請(qǐng)求頭參數(shù)
headers: {
height: 180,
weight: 180,
}
});
}
(3)axios()?常用
axios({})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//配置 baseURL
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btns[2].onclick = function () {
axios({
//請(qǐng)求方法
method: 'POST',
//url
url: '/axios-server',
//url參數(shù)
params: {
vip: 10,
level: 30
},
//頭信息,此部分如果使用自定義的頭信息,需要服務(wù)端進(jìn)行相應(yīng)修改,正常不設(shè)置
headers: {
a: 100,
b: 200
},
//請(qǐng)求體參數(shù)
data: {
username: 'admin',
password: 'admin'
}
}).then(response => {
//響應(yīng)狀態(tài)碼
console.log(response.status);
//響應(yīng)狀態(tài)字符串
console.log(response.statusText);
//響應(yīng)頭信息
console.log(response.headers);
//響應(yīng)體
console.log(response.data);
})
}
3、Fetch發(fā)送AJAX請(qǐng)求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
btn.onclick = function () {
fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
//請(qǐng)求方法
method: 'POST',
//請(qǐng)求頭
headers: {
name: 'atguigu'
},
//請(qǐng)求體
body: 'username=admin&password=admin'
}).then(response => {
// return response.text();
return response.json();
}).then(response => {
console.log(response);
});
}
四、跨域與解決
1、什么是跨域?
一個(gè)網(wǎng)頁向另一個(gè)不同域名/不同協(xié)議/不同端口的網(wǎng)頁請(qǐng)求資源。跨域原因產(chǎn)生:在當(dāng)前域名請(qǐng)求網(wǎng)站中,默認(rèn)不允許通過ajax請(qǐng)求發(fā)送其他域名。
2、為什么會(huì)產(chǎn)生跨域請(qǐng)求?
因?yàn)闉g覽器使用了同源策略
3、什么是同源策略?
同源策略是Netscape提出的一個(gè)著名的安全策略,現(xiàn)在所有支持JavaScript的瀏覽器都會(huì)使用這個(gè)策略。同源策略是瀏覽器最核心也最基本的安全功能,如果缺少同源策略,瀏覽器的正常功能可能受到影響??梢哉fweb是構(gòu)建在同源策略的基礎(chǔ)之上的,瀏覽器只是針對(duì)同源策略的一種實(shí)現(xiàn)。同源: 協(xié)議、域名、端口號(hào) 必須完全相同。?違背同源策略就是跨域。
4、為什么瀏覽器要使用同源策略?
為了保證用戶的信息安全,防止惡意網(wǎng)站竊取數(shù)據(jù),如果網(wǎng)頁之間不滿足同源要求,將不能:
(1)共享Cookie、LocalStorage、IndexDB;
(2)獲取DOM;
(3)AJAX請(qǐng)求不能發(fā)送;
5、跨域的五個(gè)解決方式:
? (1)前端使用jsonp (不推薦使用)
JSONP 是什么?
? JSONP(JSON with Padding),是一個(gè)非官方的跨域解決方案,只支持 get 請(qǐng)求。
JSONP 怎么工作的?
? 在網(wǎng)頁有一些標(biāo)簽天生具有跨域能力,比如:img link iframe script。 JSONP 就是利用 script 標(biāo)簽的跨域能力來發(fā)送請(qǐng)求的。
jsonP的使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 1. 動(dòng)態(tài)的創(chuàng)建一個(gè) script 標(biāo)簽
var script = document.createElement("script");
//2. 設(shè)置 script 的 src, 設(shè)置回調(diào)函數(shù)
script.src = "http://localhost:3000/testAJAX?callback=abc";
function abc(data) {
alert(data.name);
};
// 3. 將 script 添加到 body 中
document.body.appendChild(script);
// 4. 服務(wù)器中路由的處理------------------------------------------------------
router.get("/testAJAX", function (req, res) {
console.log("收到請(qǐng)求");
var callback = req.query.callback;
var obj = {
ame: "孫悟空",
age: 18
}
res.send(callback + "(" + JSON.stringify(obj) + ")");
});
?jQuery發(fā)送jsonP請(qǐng)求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//前端代碼
$('button').eq(0).click(function () {
$.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function (data) {
$('#result').html(`
名稱: ${data.name}
校區(qū): ${data.city}
`)
});
});
//服務(wù)端代碼
app.all('/jquery-jsonp-server', (request, response) => {
// response.send('console.log("hello jsonp")');
const data = {
name: '尚硅谷',
city: ['北京', '上海', '深圳']
};
//將數(shù)據(jù)轉(zhuǎn)化為字符串
let str = JSON.stringify(data);
//接收 callback 參數(shù)
let cb = request.query.callback;
//返回結(jié)果
response.end(`${cb}(${str})`);
});
? (2)后臺(tái)Http請(qǐng)求轉(zhuǎn)發(fā)
? (3)后臺(tái)配置同源Cors (推薦)
?2、CORS
(1)?CORS文檔鏈接
(2)CORS是什么?
?????????CORS(Cross-Origin Resource Sharing),跨域資源共享。CORS 是官方的跨域解決方案,它的特點(diǎn)是不需要在客戶端做任何特殊的操作,完全在服務(wù)器中進(jìn)行處理,支持 get 和 post 請(qǐng)求??缬蛸Y源共享標(biāo)準(zhǔn)新增了一組 HTTP 首部字段,允許服務(wù)器聲明哪些源站通過瀏覽器有權(quán)限訪問哪些資源
(3)CORS是怎么工作的?
? ????????CORS 是通過設(shè)置一個(gè)響應(yīng)頭來告訴瀏覽器,該請(qǐng)求允許跨域,瀏覽器收到該響應(yīng)以后就會(huì)對(duì)響應(yīng)放行。
Ⅰ-代碼示例
1
2
3
4
5
6
7
8
9
10
11
app.all('/cors-server', (request, response) => {
//設(shè)置響應(yīng)頭
//響應(yīng)首部中可以攜帶一個(gè) Access-Control-Allow-Origin 字段
response.setHeader("Access-Control-Allow-Origin", "*");
//Access-Control-Allow-Headers 首部字段用于預(yù)檢請(qǐng)求的響應(yīng)。其指明了實(shí)際請(qǐng)求中允許攜帶的首部字
response.setHeader("Access-Control-Allow-Headers", '*');
//Access-Control-Allow-Methods 首部字段用于預(yù)檢請(qǐng)求的響應(yīng)。其指明了實(shí)際請(qǐng)求所允許使用的 HTTP
response.setHeader("Access-Control-Allow-Method", '*');
// response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
response.send('hello CORS');
});
Ⅱ-HTTP 響應(yīng)首部字段
Access-Control-Allow-Origin
響應(yīng)首部中可以攜帶一個(gè)?Access-Control-Allow-Origin?字段,其語法如下:
1
>Access-Control-Allow-Origin:
其中,origin 參數(shù)的值指定了允許訪問該資源的外域 URI。對(duì)于不需要攜帶身份憑證的請(qǐng)求,服務(wù)器可以指定該字段的值為通配符,表示允許來自所有域的請(qǐng)求。
例如,下面的字段值將允許來自?http://mozilla.com?的請(qǐng)求:
1
>Access-Control-Allow-Origin: http://mozilla.com
如果服務(wù)端指定了具體的域名而非“*”,那么響應(yīng)首部中的 Vary 字段的值必須包含 Origin。這將告訴客戶端:服務(wù)器對(duì)不同的源站返回不同的內(nèi)容。
Access-Control-Expose-Headers
譯者注:在跨源訪問時(shí),XMLHttpRequest對(duì)象的getResponseHeader()方法只能拿到一些最基本的響應(yīng)頭,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要訪問其他頭,則需要服務(wù)器設(shè)置本響應(yīng)頭。
Access-Control-Expose-Headers?頭讓服務(wù)器把允許瀏覽器訪問的頭放入白名單,例如:
1
>Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
這樣瀏覽器就能夠通過getResponseHeader訪問X-My-Custom-Header和?X-Another-Custom-Header?響應(yīng)頭了。
Access-Control-Max-Age
Access-Control-Max-Age?頭指定了preflight請(qǐng)求的結(jié)果能夠被緩存多久,請(qǐng)參考本文在前面提到的preflight例子。
1
>Access-Control-Max-Age:
delta-seconds?參數(shù)表示preflight請(qǐng)求的結(jié)果在多少秒內(nèi)有效。
Access-Control-Allow-Credentials
Access-Control-Allow-Credentials?頭指定了當(dāng)瀏覽器的credentials設(shè)置為true時(shí)是否允許瀏覽器讀取response的內(nèi)容。當(dāng)用在對(duì)preflight預(yù)檢測(cè)請(qǐng)求的響應(yīng)中時(shí),它指定了實(shí)際的請(qǐng)求是否可以使用credentials。請(qǐng)注意:簡(jiǎn)單 GET 請(qǐng)求不會(huì)被預(yù)檢;如果對(duì)此類請(qǐng)求的響應(yīng)中不包含該字段,這個(gè)響應(yīng)將被忽略掉,并且瀏覽器也不會(huì)將相應(yīng)內(nèi)容返回給網(wǎng)頁。
1
>Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods
Access-Control-Allow-Methods?首部字段用于預(yù)檢請(qǐng)求的響應(yīng)。其指明了實(shí)際請(qǐng)求所允許使用的 HTTP 方法。
1
>Access-Control-Allow-Methods:
Access-Control-Allow-Headers
Access-Control-Allow-Headers?首部字段用于預(yù)檢請(qǐng)求的響應(yīng)。其指明了實(shí)際請(qǐng)求中允許攜帶的首部字段。
1
>Access-Control-Allow-Headers:
Ⅲ-HTTP 請(qǐng)求首部字段
本節(jié)列出了可用于發(fā)起跨源請(qǐng)求的首部字段。請(qǐng)注意,這些首部字段無須手動(dòng)設(shè)置。 當(dāng)開發(fā)者使用 XMLHttpRequest 對(duì)象發(fā)起跨源請(qǐng)求時(shí),它們已經(jīng)被設(shè)置就緒。
Origin
Origin?首部字段表明預(yù)檢請(qǐng)求或?qū)嶋H請(qǐng)求的源站。
1
>Origin:
origin 參數(shù)的值為源站 URI。它不包含任何路徑信息,只是服務(wù)器名稱。
Note:?有時(shí)候?qū)⒃撟侄蔚闹翟O(shè)置為空字符串是有用的,例如,當(dāng)源站是一個(gè) data URL 時(shí)。
注意,在所有訪問控制請(qǐng)求(Access control request)中,Origin?首部字段總是被發(fā)送
Access-Control-Request-Method
Access-Control-Request-Method?首部字段用于預(yù)檢請(qǐng)求。其作用是,將實(shí)際請(qǐng)求所使用的 HTTP 方法告訴服務(wù)器。
1
>Access-Control-Request-Method:
Access-Control-Request-Headers
Access-Control-Request-Headers?首部字段用于預(yù)檢請(qǐng)求。其作用是,將實(shí)際請(qǐng)求所攜帶的首部字段告訴服務(wù)器。
1
>Access-Control-Request-Headers:
? (4)使用SpringCloud網(wǎng)關(guān)
? (5)使用nginx做轉(zhuǎn)發(fā) (推薦)
?
五、服務(wù)端代碼示例
配合以上前端代碼的服務(wù)端代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//1. 引入express
const express = require('express');
//2. 創(chuàng)建應(yīng)用對(duì)象
const app = express();
//3. 創(chuàng)建路由規(guī)則
// request 是對(duì)請(qǐng)求報(bào)文的封裝
// response 是對(duì)響應(yīng)報(bào)文的封裝
app.get('/server', (request, response) => {
//設(shè)置響應(yīng)頭 設(shè)置允許跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//設(shè)置響應(yīng)體
response.send('HELLO AJAX - 2');
});
//可以接收任意類型的請(qǐng)求
app.all('/server', (request, response) => {
//設(shè)置響應(yīng)頭 設(shè)置允許跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//響應(yīng)頭
response.setHeader('Access-Control-Allow-Headers', '*');
//設(shè)置響應(yīng)體
response.send('HELLO AJAX POST');
});
//JSON 響應(yīng)
app.all('/json-server', (request, response) => {
//設(shè)置響應(yīng)頭 設(shè)置允許跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//響應(yīng)頭
response.setHeader('Access-Control-Allow-Headers', '*');
//響應(yīng)一個(gè)數(shù)據(jù)
const data = {
name: 'atguigu'
};
//對(duì)對(duì)象進(jìn)行字符串轉(zhuǎn)換
let str = JSON.stringify(data);
//設(shè)置響應(yīng)體
response.send(str);
});
//針對(duì) IE 緩存
app.get('/ie', (request, response) => {
//設(shè)置響應(yīng)頭 設(shè)置允許跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//設(shè)置響應(yīng)體
response.send('HELLO IE - 5');
});
//延時(shí)響應(yīng)
app.all('/delay', (request, response) => {
//設(shè)置響應(yīng)頭 設(shè)置允許跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
setTimeout(() => {
//設(shè)置響應(yīng)體
response.send('延時(shí)響應(yīng)');
}, 1000)
});
//jQuery 服務(wù)
app.all('/jquery-server', (request, response) => {
//設(shè)置響應(yīng)頭 設(shè)置允許跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
// response.send('Hello jQuery AJAX');
const data = {
name: '尚硅谷'
};
response.send(JSON.stringify(data));
});
//axios 服務(wù)
app.all('/axios-server', (request, response) => {
//設(shè)置響應(yīng)頭 設(shè)置允許跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
// response.send('Hello jQuery AJAX');
const data = {
name: '尚硅谷'
};
response.send(JSON.stringify(data));
});
//fetch 服務(wù)
app.all('/fetch-server', (request, response) => {
//設(shè)置響應(yīng)頭 設(shè)置允許跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
// response.send('Hello jQuery AJAX');
const data = {
name: '尚硅谷'
};
response.send(JSON.stringify(data));
});
//jsonp服務(wù)
app.all('/jsonp-server', (request, response) => {
// response.send('console.log("hello jsonp")');
const data = {
name: '尚硅谷atguigu'
};
//將數(shù)據(jù)轉(zhuǎn)化為字符串
let str = JSON.stringify(data);
//返回結(jié)果
response.end(`handle(${str})`);
});
//用戶名檢測(cè)是否存在
app.all('/check-username', (request, response) => {
// response.send('console.log("hello jsonp")');
const data = {
exist: 1,
msg: '用戶名已經(jīng)存在'
};
//將數(shù)據(jù)轉(zhuǎn)化為字符串
let str = JSON.stringify(data);
//返回結(jié)果
response.end(`handle(${str})`);
});
//
app.all('/jquery-jsonp-server', (request, response) => {
// response.send('console.log("hello jsonp")');
const data = {
name: '尚硅谷',
city: ['北京', '上海', '深圳']
};
//將數(shù)據(jù)轉(zhuǎn)化為字符串
let str = JSON.stringify(data);
//接收 callback 參數(shù)
let cb = request.query.callback;
//返回結(jié)果
response.end(`${cb}(${str})`);
});
app.all('/cors-server', (request, response) => {
//設(shè)置響應(yīng)頭
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", '*');
response.setHeader("Access-Control-Allow-Method", '*');
// response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
response.send('hello CORS');
});
//4. 監(jiān)聽端口啟動(dòng)服務(wù)
app.listen(8000, () => {
console.log("服務(wù)已經(jīng)啟動(dòng), 8000 端口監(jiān)聽中....");
});
柚子快報(bào)邀請(qǐng)碼778899分享:前端 Ajax的簡(jiǎn)介和使用
參考文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。