å°ç®å为æ¢ï¼æä»¬å·²ç»å¯¹ fetch ç¸å½äºè§£äºã
ç°å¨è®©æä»¬æ¥çç fetch çå©ä½ APIï¼æ¥äºè§£å®çå
¨é¨æ¬é¢å§ã
请注æï¼è¿äºé项 (option) 大å¤é½å¾å°ä½¿ç¨ãå³ä½¿è·³è¿æ¬ç« ï¼ä½ ä¹å¯ä»¥å¾å¥½å°ä½¿ç¨ fetchã
使¯ï¼ç¥é fetch å¯ä»¥åä»ä¹è¿æ¯å¾å¥½çï¼æä»¥å¦æéè¦ï¼ä½ å¯ä»¥æ¥ççè¿äºç»èå
容ã
è¿æ¯ææå¯è½ç fetch é项åå
¶é»è®¤å¼ï¼æ³¨é䏿 注äºå¯éå¼ï¼ç宿´å表ï¼
let promise = fetch(url, {
method: "GET", // POSTï¼PUTï¼DELETEï¼çã
headers: {
// å
容类å header å¼é常æ¯èªå¨è®¾ç½®ç
// åå³äº request body
"Content-Type": "text/plain;charset=UTF-8"
},
body: undefined // stringï¼FormDataï¼Blobï¼BufferSourceï¼æ URLSearchParams
referrer: "about:client", // æ "" 以ä¸åé Referer headerï¼
// æè
æ¯å½åæºç url
referrerPolicy: "no-referrer-when-downgrade", // no-referrerï¼originï¼same-origin...
mode: "cors", // same-originï¼no-cors
credentials: "same-origin", // omitï¼include
cache: "default", // no-storeï¼reloadï¼no-cacheï¼force-cacheï¼æ only-if-cached
redirect: "follow", // manualï¼error
integrity: "", // ä¸ä¸ª hashï¼å "sha256-abcdef1234567890"
keepalive: false, // true
signal: undefined, // AbortController æ¥ä¸æ¢è¯·æ±
window: window // null
});
ä¸ä¸ªä»¤äººå°è±¡æ·±å»çå表ï¼å¯¹å§?
æä»¬å·²ç»å¨ Fetch ä¸ç« ä¸è¯¦ç»ä»ç»äº methodï¼headers å bodyã
å¨ Fetchï¼ä¸æ¢ï¼Abortï¼ ä¸ç« ä¸ä»ç»äº signal é项ã
ç°å¨è®©æä»¬ä¸èµ·æ¢ç´¢å ¶ä½çåè½ã
referrerï¼referrerPolicy
è¿äºé项å³å®äº fetch å¦ä½è®¾ç½® HTTP ç Referer headerã
é常æ¥è¯´ï¼è¿ä¸ª header æ¯è¢«èªå¨è®¾ç½®çï¼å¹¶å å«äºååºè¯·æ±ç页é¢ç urlãå¨å¤§å¤æ°æ åµä¸ï¼å®ä¸ç¹ä¹ä¸éè¦ï¼ä½ææ¶åºäºå®å ¨èèï¼å é¤æç¼©ç宿¯ææä¹çã
referrer é项å
è®¸è®¾ç½®ä»»ä½ Refererï¼å¨å½ååçï¼ï¼æè
ç§»é¤å®ã
妿䏿³åé referrerï¼å¯ä»¥å° referrer 设置为空å符串ï¼
fetch('/page', {
referrer: "" // 没æ Referer header
});
设置å¨å½ååå çå¦ä¸ä¸ª urlï¼
fetch('/page', {
// å设æä»¬å¨ https://javascript.info
// æä»¬å¯ä»¥è®¾ç½®ä»»ä½ Referer headerï¼ä½å¿
é¡»æ¯å¨å½ååå
ç
referrer: "https://javascript.info/anotherpage"
});
referrerPolicy é项为 Referer 设置ä¸è¬çè§åã
请æ±å为 3 ç§ç±»åï¼
- åæºè¯·æ±ã
- è·¨æºè¯·æ±ã
- ä» HTTPS å° HTTP çè¯·æ± (ä»å®å ¨åè®®å°ä¸å®å ¨åè®®)ã
ä¸ referrer é项å
许设置确åç Referer å¼ä¸åï¼referrerPolicy åè¯æµè§å¨é对å个请æ±ç±»åçä¸è¬çè§åã
å¯è½çå¼å¨ Referrer Policy è§èä¸æè¯¦ç»æè¿°ï¼
"no-referrer-when-downgrade"ââ é»è®¤å¼ï¼é¤éæä»¬ä» HTTPS åé请æ±å° HTTPï¼å°å®å ¨æ§è¾ä½çåè®®ï¼ï¼å¦åå§ç»ä¼åé宿´çRefererã"no-referrer"ââ ä»ä¸åéRefererã"origin"ââ åªåéå¨Refererä¸çåï¼è䏿¯å®æ´çé¡µé¢ URLï¼ä¾å¦ï¼åªåéhttp://site.comè䏿¯http://site.com/pathã"origin-when-cross-origin"ââ åé宿´çRefererå°ç¸åçæºï¼ä½å¯¹äºè·¨æºè¯·æ±ï¼åªåéåé¨åï¼åä¸ï¼ã"same-origin"ââ åé宿´çRefererå°ç¸åçæºï¼ä½å¯¹äºè·¨æºè¯·æ±ï¼ä¸åéRefererã"strict-origin"ââ åªåéåï¼å¯¹äº HTTPSâHTTP 请æ±ï¼åä¸åéRefererã"strict-origin-when-cross-origin"ââ 对äºåæºæ åµä¸ååé宿´çRefererï¼å¯¹äºè·¨æºæ åµä¸ï¼ååªåéåï¼å¦ææ¯ HTTPSâHTTP 请æ±ï¼åä»ä¹é½ä¸åéã"unsafe-url"ââ å¨Refererä¸å§ç»åé宿´ç urlï¼å³ä½¿æ¯ HTTPSâHTTP 请æ±ã
è¿æ¯ä¸ä¸ªå 嫿æç»åçè¡¨æ ¼ï¼
| å¼ | åæº | è·¨æº | HTTPSâHTTP |
|---|---|---|---|
"no-referrer" |
- | - | - |
"no-referrer-when-downgrade" æ ""ï¼é»è®¤ï¼ |
宿´ç url | 宿´ç url | - |
"origin" |
ä» å | ä» å | ä» å |
"origin-when-cross-origin" |
宿´ç url | ä» å | ä» å |
"same-origin" |
宿´ç url | - | - |
"strict-origin" |
ä» å | ä» å | - |
"strict-origin-when-cross-origin" |
宿´ç url | ä» å | - |
"unsafe-url" |
宿´ç url | 宿´ç url | 宿´ç url |
å妿们æä¸ä¸ªå¸¦æ URL ç»æç管çåºåï¼admin zoneï¼ï¼å®ä¸åºè¯¥è¢«ä»ç½ç«å¤çå°ã
妿æä»¬åéäºä¸ä¸ª fetchï¼åé»è®¤æ
åµä¸ï¼å®æ»æ¯åé带æé¡µé¢å®æ´ url ç Referer headerï¼æä»¬ä» HTTPS å HTTP åé请æ±çæ
åµé¤å¤ï¼è¿ç§æ
åµä¸æ²¡æ Refererï¼ã
ä¾å¦ Referer: https://javascript.info/admin/secret/pathsã
妿æä»¬æ³è®©å ¶ä»ç½ç«åªç¥éåçé¨åï¼è䏿¯ URL è·¯å¾ï¼æä»¬å¯ä»¥è¿æ ·è®¾ç½®é项ï¼
fetch('https://another.com/page', {
// ...
referrerPolicy: "origin-when-cross-origin" // Referer: https://javascript.info
});
æä»¬å¯ä»¥å°å
¶ç½®äºææ fetch è°ç¨ä¸ï¼ä¹å¯ä»¥å°å
¶éæå°æä»¬é¡¹ç®çæ§è¡ææè¯·æ±å¹¶å¨å
é¨ä½¿ç¨ fetch ç JavaScript åºä¸ã
ä¸é»è®¤è¡ä¸ºç¸æ¯ï¼å®çå¯ä¸åºå«å¨äºï¼å¯¹äºè·¨æºè¯·æ±ï¼fetch åªåé URL åçé¨åï¼ä¾å¦ https://javascript.infoï¼æ²¡æè·¯å¾ï¼ã对äºåæºè¯·æ±ï¼æä»¬ä»ç¶å¯ä»¥è·å¾å®æ´ç Refererï¼å¯è½å¯¹äºè°è¯ç®çæ¯æç¨çï¼ã
fetchå¨ è§è ä¸æè¿°ç referrer policyï¼ä¸ä»
éç¨äº fetchï¼å®è¿å
·æå
¨å±æ§ã
ç¹å«æ¯ï¼å¯ä»¥ä½¿ç¨ Referrer-Policy HTTP headerï¼æè
为æ¯ä¸ªé¾æ¥è®¾ç½® <a rel="noreferrer">ï¼æ¥ä¸ºæ´ä¸ªé¡µé¢è®¾ç½®é»è®¤çç¥ï¼policyï¼ã
mode
mode é项æ¯ä¸ç§å®å
¨æªæ½ï¼å¯ä»¥é²æ¢å¶åçè·¨æºè¯·æ±ï¼
"cors"ââ é»è®¤å¼ï¼å 许跨æºè¯·æ±ï¼å¦ Fetchï¼è·¨æºè¯·æ± ä¸ç« æè¿°ï¼"same-origin"ââ ç¦æ¢è·¨æºè¯·æ±ï¼"no-cors"ââ åªå 许å®å ¨çè·¨æºè¯·æ±ã
å½ fetch ç URL æ¥èªäºç¬¬ä¸æ¹ï¼å¹¶ä¸æä»¬æ³è¦ä¸ä¸ªâæçµå¼å
³âæ¥éå¶è·¨æºè½åæ¶ï¼æ¤é项å¯è½å¾æç¨ã
credentials
credentials é项æå® fetch æ¯å¦åºè¯¥é请æ±åé cookie å HTTP-Authorization headerã
"same-origin"ââ é»è®¤å¼ï¼å¯¹äºè·¨æºè¯·æ±ä¸åéï¼"include"ââ æ»æ¯åéï¼éè¦æ¥èªè·¨æºæå¡å¨çAccess-Control-Allow-Credentialsï¼æè½ä½¿ JavaScript è½å¤è®¿é®ååºï¼è¯¦ç»å å®¹å¨ Fetchï¼è·¨æºè¯·æ± ä¸ç« æè¯¦ç»ä»ç»ï¼"omit"ââ ä¸åéï¼å³ä½¿å¯¹äºåæºè¯·æ±ã
cache
é»è®¤æ
åµä¸ï¼fetch 请æ±ä½¿ç¨æ åç HTTP ç¼åãå°±æ¯è¯´ï¼å®éµä» Expiresï¼Cache-Control headerï¼åé If-Modified-Sinceï¼çãå°±å常è§ç HTTP 请æ±é£æ ·ã
ä½¿ç¨ cache é项å¯ä»¥å¿½ç¥ HTTP ç¼åæè
对å
¶ç¨æ³è¿è¡å¾®è°ï¼
"default"ââfetchä½¿ç¨æ åç HTTP ç¼åè§åå headerï¼"no-store"ââ å®å ¨å¿½ç¥ HTTP ç¼åï¼å¦ææä»¬è®¾ç½® headerIf-Modified-Sinceï¼If-None-Matchï¼If-Unmodified-Sinceï¼If-Matchï¼æIf-Rangeï¼åæ¤æ¨¡å¼ä¼æä¸ºé»è®¤æ¨¡å¼ï¼"reload"ââ ä¸ä» HTTP ç¼åä¸è·åç»æï¼å¦ææï¼ï¼èæ¯ä½¿ç¨ååºå¡«å ç¼åï¼å¦æ response header å è®¸æ¤æä½ï¼ï¼"no-cache"ââ 妿æä¸ä¸ªå·²ç¼åçååºï¼åå建ä¸ä¸ªææ¡ä»¶ç请æ±ï¼å¦åå建ä¸ä¸ªæ®éç请æ±ã使ç¨ååºå¡«å HTTP ç¼åï¼"force-cache"ââ ä½¿ç¨æ¥èª HTTP ç¼åçååºï¼å³ä½¿è¯¥ååºå·²è¿æ¶ï¼staleï¼ã妿 HTTP ç¼å䏿²¡æååºï¼åå建ä¸ä¸ªå¸¸è§ç HTTP 请æ±ï¼è¡ä¸ºåæ£å¸¸é£æ ·ï¼"only-if-cached"ââ ä½¿ç¨æ¥èª HTTP ç¼åçååºï¼å³ä½¿è¯¥ååºå·²è¿æ¶ï¼staleï¼ã妿 HTTP ç¼å䏿²¡æååºï¼åæ¥éãåªæå½mode为same-originæ¶çæã
redirect
é常æ¥è¯´ï¼fetch éæå°éµå¾ª HTTP éå®åï¼ä¾å¦ 301ï¼302 çã
redirect é项å
许对æ¤è¿è¡æ´æ¹ï¼
"follow"ââ é»è®¤å¼ï¼éµå¾ª HTTP éå®åï¼"error"ââ HTTP éå®åæ¶æ¥éï¼"manual"ââ å 许æå¨å¤ç HTTP éå®åãå¨éå®åçæ åµä¸ï¼æä»¬å°è·å¾ä¸ä¸ªç¹æ®çååºå¯¹è±¡ï¼å ¶ä¸å å«response.type="opaqueredirect"åå½é¶/ç©ºç¶æä»¥å大夿°å ¶ä»å±æ§ã
integrity
integrity é项å
è®¸æ£æ¥ååºæ¯å¦ä¸å·²ç¥çé¢å
æ ¡éªåç¸å¹é
ã
æ£å¦ è§è ææè¿°çï¼æ¯æçåå¸å½æ°æ SHA-256ï¼SHA-384ï¼å SHA-512ï¼å¯è½è¿æå ¶ä»çï¼è¿åå³äºæµè§å¨ã
ä¾å¦ï¼æä»¬ä¸è½½ä¸ä¸ªæä»¶ï¼å¹¶ä¸æä»¬ç¥éå®ç SHA-256 æ ¡éªå为 âabcdefâï¼å½ç¶ï¼å®é æ ¡éªå伿´é¿ï¼ã
æä»¬å¯ä»¥å°å
¶æ¾å¨ integrity é项ä¸ï¼å°±åè¿æ ·:
fetch('http://site.com/file', {
integrity: 'sha256-abcdef'
});
ç¶å fetch å°èªè¡è®¡ç® SHA-256 å¹¶å°å
¶ä¸æä»¬çå符串è¿è¡æ¯è¾ã妿ä¸å¹é
ï¼åä¼è§¦åé误ã
keepalive
keepalive é项表示该请æ±å¯è½ä¼å¨ç½é¡µå
³éåç»§ç»åå¨ã
ä¾å¦ï¼æä»¬æ¶éæå ³å½å访é®è æ¯å¦ä½ä½¿ç¨æä»¬ç页é¢ï¼é¼ æ ç¹å»ï¼ä»æ¥çç页é¢ç段ï¼çç»è®¡ä¿¡æ¯ï¼ä»¥åæåæ¹åç¨æ·ä½éªã
å½è®¿é®è ç¦»å¼æä»¬çç½é¡µæ¶ ââ æä»¬å¸æè½å¤å°æ°æ®ä¿å尿们çæå¡å¨ä¸ã
æä»¬å¯ä»¥ä½¿ç¨ window.onunload äºä»¶æ¥å®ç°ï¼
window.onunload = function() {
fetch('/analytics', {
method: 'POST',
body: "statistics",
keepalive: true
});
};
é常ï¼å½ä¸ä¸ªææ¡£è¢«å¸è½½æ¶ï¼unloadedï¼ï¼ææç¸å
³çç½ç»è¯·æ±é½ä¼è¢«ä¸æ¢ã使¯ï¼keepalive é项åè¯æµè§å¨ï¼å³ä½¿å¨ç¦»å¼é¡µé¢åï¼ä¹è¦å¨åå°æ§è¡è¯·æ±ãæä»¥ï¼æ¤éé¡¹å¯¹äºæä»¬çè¯·æ±æåè³å
³éè¦ã
宿ä¸äºéå¶ï¼
- æä»¬æ æ³åéå
åèçæ°æ®ï¼
keepalive请æ±ç body éå¶ä¸º 64KBã- 妿æä»¬éè¦æ¶éæå
³è®¿é®ç大éç»è®¡ä¿¡æ¯ï¼æä»¬ååºè¯¥å°å
¶å®æä»¥æ°æ®å
çå½¢å¼åéåºå»ï¼è¿æ ·å°±ä¸ä¼çä¸å¤ªå¤æ°æ®ç»æåç
onunload请æ±äºã - æ¤éå¶æ¯è¢«åºç¨äºå½åææ
keepalive请æ±çæ»åçãæ¢å¥è¯è¯´ï¼æä»¬å¯ä»¥å¹¶è¡æ§è¡å¤ä¸ªkeepalive请æ±ï¼ä½å®ä»¬ç body é¿åº¦ä¹åä¸å¾è¶ è¿ 64KBã
- 妿æä»¬éè¦æ¶éæå
³è®¿é®ç大éç»è®¡ä¿¡æ¯ï¼æä»¬ååºè¯¥å°å
¶å®æä»¥æ°æ®å
çå½¢å¼åéåºå»ï¼è¿æ ·å°±ä¸ä¼çä¸å¤ªå¤æ°æ®ç»æåç
- å¦æææ¡£ï¼documentï¼å·²å¸è½½ï¼unloadedï¼ï¼æä»¬å°±æ æ³å¤çæå¡å¨ååºãå æ¤ï¼å¨æä»¬ç示ä¾ä¸ï¼å 为
keepaliveï¼æä»¥fetch伿åï¼ä½æ¯åç»ç彿°å°æ æ³æ£å¸¸å·¥ä½ã- å¨å¤§å¤æ°æ åµä¸ï¼ä¾å¦åéç»è®¡ä¿¡æ¯ï¼è¿ä¸æ¯é®é¢ï¼å 为æå¡å¨åªæ¥æ¶æ°æ®ï¼å¹¶éå¸¸åæ¤ç±»è¯·æ±åé空çååºã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼