JavaScript å¯ä»¥å°ç½ç»è¯·æ±åéå°æå¡å¨ï¼å¹¶å¨éè¦æ¶å è½½æ°ä¿¡æ¯ã
ä¾å¦ï¼æä»¬å¯ä»¥ä½¿ç¨ç½ç»è¯·æ±æ¥ï¼
- æäº¤è®¢åï¼
- å è½½ç¨æ·ä¿¡æ¯ï¼
- 仿å¡å¨æ¥æ¶ææ°çæ´æ°ï¼
- â¦â¦çã
â¦â¦ææè¿äºé½æ²¡æéæ°å 载页é¢ï¼
å¯¹äºæ¥èª JavaScript çç½ç»è¯·æ±ï¼æä¸ä¸ªæ»ç§°æ¯è¯ âAJAXâï¼Asynchronous JavaScript And XML çç®ç§°ï¼ã使¯ï¼æä»¬ä¸å¿ ä½¿ç¨ XMLï¼è¿ä¸ªæ¯è¯è¯çäºå¾ä¹ 以åï¼æä»¥è¿ä¸ªè¯ä¸ç´å¨é£å¿ã
æå¾å¤æ¹å¼å¯ä»¥åæå¡å¨åéç½ç»è¯·æ±ï¼å¹¶ä»æå¡å¨è·åä¿¡æ¯ã
fetch() æ¹æ³æ¯ä¸ç§ç°ä»£éç¨çæ¹æ³ï¼é£ä¹æä»¬å°±ä»å®å¼å§å§ãæ§çæ¬çæµè§å¨ä¸æ¯æå®ï¼å¯ä»¥ polyfillï¼ï¼ä½æ¯å®å¨ç°ä»£æµè§å¨ä¸çæ¯ææ
åµå¾å¥½ã
åºæ¬è¯æ³ï¼
let promise = fetch(url, [options])
urlââ è¦è®¿é®ç URLãoptionsââ å¯éåæ°ï¼methodï¼header çã
没æ optionsï¼è¿å°±æ¯ä¸ä¸ªç®åç GET 请æ±ï¼ä¸è½½ url çå
容ã
æµè§å¨ç«å³å¯å¨è¯·æ±ï¼å¹¶è¿åä¸ä¸ªè¯¥è°ç¨ä»£ç åºè¯¥ç¨æ¥è·åç»æç promiseã
è·åååºé常éè¦ç»è¿ä¸¤ä¸ªé¶æ®µã
第ä¸é¶æ®µï¼å½æå¡å¨åéäºååºå¤´ï¼response headerï¼ï¼fetch è¿åç promise 就使ç¨å
建ç Response class 对象æ¥å¯¹ååºå¤´è¿è¡è§£æã
å¨è¿ä¸ªé¶æ®µï¼æä»¬å¯ä»¥éè¿æ£æ¥ååºå¤´ï¼æ¥æ£æ¥ HTTP ç¶æä»¥ç¡®å®è¯·æ±æ¯å¦æåï¼å½åè¿æ²¡æååºä½ï¼response bodyï¼ã
妿 fetch æ æ³å»ºç«ä¸ä¸ª HTTP 请æ±ï¼ä¾å¦ç½ç»é®é¢ï¼äº¦ææ¯è¯·æ±çç½åä¸åå¨ï¼é£ä¹ promise å°±ä¼ rejectãå¼å¸¸ç HTTP ç¶æï¼ä¾å¦ 404 æ 500ï¼ä¸ä¼å¯¼è´åºç° errorã
æä»¬å¯ä»¥å¨ response ç屿§ä¸çå° HTTP ç¶æï¼
statusââ HTTP ç¶æç ï¼ä¾å¦ 200ãokââ å¸å°å¼ï¼å¦æ HTTP ç¶æç 为 200-299ï¼å为trueã
ä¾å¦ï¼
let response = await fetch(url);
if (response.ok) { // 妿 HTTP ç¶æç 为 200-299
// è·å response bodyï¼æ¤æ¹æ³ä¼å¨ä¸é¢è§£éï¼
let json = await response.json();
} else {
alert("HTTP-Error: " + response.status);
}
第äºé¶æ®µï¼ä¸ºäºè·å response bodyï¼æä»¬éè¦ä½¿ç¨ä¸ä¸ªå ¶ä»çæ¹æ³è°ç¨ã
Response æä¾äºå¤ç§åºäº promise çæ¹æ³ï¼æ¥ä»¥ä¸åçæ ¼å¼è®¿é® bodyï¼
response.text()ââ 读å responseï¼å¹¶ä»¥ææ¬å½¢å¼è¿å responseï¼response.json()ââ å° response è§£æä¸º JSON æ ¼å¼ï¼response.formData()ââ 以FormData对象ï¼å¨ ä¸ä¸ç« æè§£éï¼çå½¢å¼è¿å responseï¼response.blob()ââ 以 Blobï¼å ·æç±»åçäºè¿å¶æ°æ®ï¼å½¢å¼è¿å responseï¼response.arrayBuffer()ââ 以 ArrayBufferï¼ä½çº§å«çäºè¿å¶æ°æ®ï¼å½¢å¼è¿å responseï¼- å¦å¤ï¼
response.bodyæ¯ ReadableStream 对象ï¼å®å è®¸ä½ éå读å bodyï¼æä»¬ç¨åä¼ç¨ä¸ä¸ªä¾åè§£éå®ã
ä¾å¦ï¼æä»¬ä» GitHub è·åææ° commits ç JSON 对象ï¼
let url = 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits';
let response = await fetch(url);
let commits = await response.json(); // 读å response bodyï¼å¹¶å°å
¶è§£æä¸º JSON æ ¼å¼
alert(commits[0].author.login);
ä¹å¯ä»¥ä½¿ç¨çº¯ promise è¯æ³ï¼ä¸ä½¿ç¨ awaitï¼
fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits')
.then(response => response.json())
.then(commits => alert(commits[0].author.login));
è¦è·åååºææ¬ï¼å¯ä»¥ä½¿ç¨ await response.text() ä»£æ¿ .json()ï¼
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
let text = await response.text(); // å° response body 读åä¸ºææ¬
alert(text.slice(0, 80) + '...');
ä½ä¸ºä¸ä¸ªè¯»å为äºè¿å¶æ ¼å¼çæ¼ç¤ºç¤ºä¾ï¼è®©æä»¬ fetch å¹¶æ¾ç¤ºä¸å¼ âfetchâ è§è ä¸çå¾çï¼Blob æä½çæå
³å
å®¹è¯·è§ Blobï¼ï¼
let response = await fetch('/article/fetch/logo-fetch.svg');
let blob = await response.blob(); // ä¸è½½ä¸º Blob 对象
// 为å
¶å建ä¸ä¸ª <img>
let img = document.createElement('img');
img.style = 'position:fixed;top:10px;left:10px;width:100px';
document.body.append(img);
// æ¾ç¤ºå®
img.src = URL.createObjectURL(blob);
setTimeout(() => { // 3 ç§åå°å
¶éè
img.remove();
URL.revokeObjectURL(img.src);
}, 3000);
æä»¬åªè½éæ©ä¸ç§è¯»å body çæ¹æ³ã
妿æä»¬å·²ç»ä½¿ç¨äº response.text() æ¹æ³æ¥è·å responseï¼é£ä¹å¦æåç¨ response.json()ï¼åä¸ä¼çæï¼å 为 body å
容已ç»è¢«å¤çè¿äºã
let text = await response.text(); // response body 被å¤çäº
let parsed = await response.json(); // 失败ï¼å·²ç»è¢«å¤çè¿äºï¼
Response header
Response header ä½äº response.headers ä¸çä¸ä¸ªç±»ä¼¼äº Map ç header 对象ã
å®ä¸æ¯çæ£ç Mapï¼ä½æ¯å®å ·æç±»ä¼¼çæ¹æ³ï¼æä»¬å¯ä»¥æåç§°ï¼nameï¼è·åå个 headerï¼æè¿ä»£å®ä»¬ï¼
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
// è·åä¸ä¸ª header
alert(response.headers.get('Content-Type')); // application/json; charset=utf-8
// è¿ä»£ææ header
for (let [key, value] of response.headers) {
alert(`${key} = ${value}`);
}
Request header
è¦å¨ fetch ä¸è®¾ç½® request headerï¼æä»¬å¯ä»¥ä½¿ç¨ headers é项ã宿ä¸ä¸ªå¸¦æè¾åº header ç对象ï¼å¦ä¸æç¤ºï¼
let response = fetch(protectedUrl, {
headers: {
Authentication: 'secret'
}
});
â¦â¦ä½æ¯æä¸äºæä»¬æ æ³è®¾ç½®ç headerï¼è¯¦è§ forbidden HTTP headersï¼ï¼
Accept-Charset,Accept-EncodingAccess-Control-Request-HeadersAccess-Control-Request-MethodConnectionContent-LengthCookie,Cookie2DateDNTExpectHostKeep-AliveOriginRefererTETrailerTransfer-EncodingUpgradeViaProxy-*Sec-*
è¿äº header ä¿è¯äº HTTP çæ£ç¡®æ§åå®å ¨æ§ï¼æä»¥å®ä»¬ä» ç±æµè§å¨æ§å¶ã
POST 请æ±
è¦å建ä¸ä¸ª POST 请æ±ï¼æè
å
¶ä»æ¹æ³ç请æ±ï¼æä»¬éè¦ä½¿ç¨ fetch é项ï¼
methodââ HTTP æ¹æ³ï¼ä¾å¦POSTï¼bodyââ request bodyï¼å ¶ä¸ä¹ä¸ï¼- å符串ï¼ä¾å¦ JSON ç¼ç çï¼ï¼
FormData对象ï¼ä»¥multipart/form-dataå½¢å¼åéæ°æ®ï¼Blob/BufferSourceåéäºè¿å¶æ°æ®ï¼- URLSearchParamsï¼ä»¥
x-www-form-urlencodedç¼ç å½¢å¼åéæ°æ®ï¼å¾å°ä½¿ç¨ã
JSON 形弿¯æå¸¸ç¨çã
ä¾å¦ï¼ä¸é¢è¿æ®µä»£ç 以 JSON å½¢å¼åé user 对象ï¼
let user = {
name: 'John',
surname: 'Smith'
};
let response = await fetch('/article/fetch/post/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(user)
});
let result = await response.json();
alert(result.message);
请注æï¼å¦æè¯·æ±ç body æ¯å符串ï¼å Content-Type ä¼é»è®¤è®¾ç½®ä¸º text/plain;charset=UTF-8ã
使¯ï¼å½æä»¬è¦åé JSON æ¶ï¼æä»¬ä¼ä½¿ç¨ headers é项æ¥åé application/jsonï¼è¿æ¯ JSON ç¼ç çæ°æ®çæ£ç¡®ç Content-Typeã
åéå¾ç
æä»¬åæ ·å¯ä»¥ä½¿ç¨ Blob æ BufferSource 对象éè¿ fetch æäº¤äºè¿å¶æ°æ®ã
ä¾å¦ï¼è¿éæä¸ä¸ª <canvas>ï¼æä»¬å¯ä»¥éè¿å¨å
¶ä¸ç§»å¨é¼ æ æ¥è¿è¡ç»å¶ãç¹å» âsubmitâ æé®å°å¾çåéå°æå¡å¨ï¼
<body style="margin:0">
<canvas id="canvasElem" width="100" height="80" style="border:1px solid"></canvas>
<input type="button" value="Submit" onclick="submit()">
<script>
canvasElem.onmousemove = function(e) {
let ctx = canvasElem.getContext('2d');
ctx.lineTo(e.clientX, e.clientY);
ctx.stroke();
};
async function submit() {
let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
let response = await fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
});
// æå¡å¨ç»åºç¡®è®¤ä¿¡æ¯åå¾ç大å°ä½ä¸ºååº
let result = await response.json();
alert(result.message);
}
</script>
</body>
请注æï¼è¿éæä»¬æ²¡ææå¨è®¾ç½® Content-Type headerï¼å 为 Blob 对象å
·æå
建çç±»åï¼è¿éæ¯ image/pngï¼éè¿ toBlob çæçï¼ãå¯¹äº Blob 对象ï¼è¿ä¸ªç±»åå°±åæäº Content-Type çå¼ã
å¯ä»¥å¨ä¸ä½¿ç¨ async/await çæ
åµä¸éå submit() 彿°ï¼åè¿æ ·ï¼
function submit() {
canvasElem.toBlob(function(blob) {
fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
})
.then(response => response.json())
.then(result => alert(JSON.stringify(result, null, 2)))
}, 'image/png');
}
æ»ç»
å
¸åç fetch 请æ±ç±ä¸¤ä¸ª await è°ç¨ç»æï¼
let response = await fetch(url, options); // è§£æ response header
let result = await response.json(); // å° body 读å为 json
æè 以 promise å½¢å¼ï¼
fetch(url, options)
.then(response => response.json())
.then(result => /* process result */)
ååºç屿§ï¼
response.statusââ response ç HTTP ç¶æç ï¼response.okââ HTTP ç¶æç 为 200-299ï¼å为trueãresponse.headersââ ç±»ä¼¼äº Map ç带æ HTTP header ç对象ã
è·å response body çæ¹æ³ï¼
response.text()ââ 读å responseï¼å¹¶ä»¥ææ¬å½¢å¼è¿å responseï¼response.json()ââ å° response è§£æä¸º JSON 对象形å¼ï¼response.formData()ââ 以FormData对象ï¼multipart/form-dataç¼ç ï¼åè§ä¸ä¸ç« ï¼çå½¢å¼è¿å responseï¼response.blob()ââ 以 Blobï¼å ·æç±»åçäºè¿å¶æ°æ®ï¼å½¢å¼è¿å responseï¼response.arrayBuffer()ââ 以 ArrayBufferï¼ä½çº§å«çäºè¿å¶æ°æ®ï¼å½¢å¼è¿å responseã
å°ç®åä¸ºæ¢æä»¬äºè§£å°ç fetch é项ï¼
methodââ HTTP æ¹æ³ï¼headersââ å ·æ request header ç对象ï¼ä¸æ¯ææ header 齿¯è¢«å 许çï¼bodyââ è¦ä»¥stringï¼FormDataï¼BufferSourceï¼BlobæUrlSearchParams对象çå½¢å¼åéçæ°æ®ï¼request bodyï¼ã
å¨ä¸ä¸ç« ï¼æä»¬å°ä¼çå°æ´å¤ fetch çé项åç¨ä¾ã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼