01ã为ä»ä¹è¦è·¨åï¼
è·¨åçæ ¹æ¬åå æ¯æµè§å¨çâåæºçç¥âï¼å¾å äºè§£ä»ä¹æ¯åæºï¼ââ å°±æ¯ãåè®®+åå+端å£å·ãç¸åï¼å³ä¸ºåæºï¼åªè½ååæºçæå¡åèµ·AJAX请æ±ã
æº1 | æº2 | æ¯å¦åæº |
---|---|---|
a.com | b.com | ð«ä¸åæºï¼ååä¸å |
http://a.com | https://a.com | ð«ä¸åæºï¼åè®®ä¸å |
a.com:80 | a.com:443 | ð«ä¸åæºï¼ç«¯å£ä¸å |
gg.com | a.gg.com | ð«ä¸åæºï¼åååä¸å |
a.com/ss | a.com/s2 | åæº |
å¯éè¿
location.origin
ãwindow.origin
è·åå½åææ¡£çæº
â为ä»ä¹è¦åæºå¢ï¼
è¿æ¯æµè§å¨æ æ设计çï¼æ¯æµè§å¨çåºæ¬å®å ¨çç¥ï¼å¦åä¼å¾å®¹æåå°XSSãCSRFæ»å»ãåªè½ååæºçæå¡åèµ·AJAX请æ±ï¼ä¸å¯è·¨å请æ±ï¼ä¼è¢«æµè§å¨æ¦æªã
âæåªäºéå¶è§åå¢ï¼
- â
访é®å
¶ä»æºçå¾çãCSSãJSæ¯å¯ä»¥çï¼å
许
<img src="url">
ã<link href="url">
ã<script src="url">
å ç´ è·åçå ¶ä»æºçèµæºã - â Form表åå¯ä»¥è·¨åæ交ï¼è¡¨åçæ交åªæ¯æ交æ°æ®æ éè¿åï¼æµè§å¨è®¤ä¸ºæ¯å®å ¨çã
- ð« AJAXä¸å¯ä»¥åå ¶ä»æºåéç½ç»è¯·æ±ï¼ä¼è¢«æµè§å¨æ¦æªã注ææ¦æªçä¸æ¯è¯·æ±ï¼èæ¯ååºï¼æå¡ç«¯ä¾ç¶æ¯å¯ä»¥æ¶å°è¯·æ±çã
- ð« ä» å¯è®¿é®èªå·±åçcookieãlocalStorageãDOMæ ï¼ä¸è½è®¿é®Iframeåµå ¥çå ¶ä»é¡µé¢å é¨å 容ã
02ãå¦ä½å®ç°è·¨åï¼
éçäºèç½è¶æ¥è¶å¤æï¼éæ±ä¹è¶æ¥è¶å¤ï¼è·¨å请æ±å°±å¾å¸¸è§äºãæ们ç¥éäºè·¨åæ¯æµè§å¨çåæºéå¶ï¼å°±å¯ä»¥é对æ§çæ³åæ³äºã
2.1ãJSONPè·¨å
è¿æ¯ä¸ç§ä¼ ç»çè·¨å请æ±åæ³ï¼åå©äº<script>
æ ç¾å
ç´ ï¼å 为<script>
çsrc
å¯ä»¥è®¿é®ä»»ä½ç«ç¹çèµæºãå½ç¶è¿éè¦æå¡ç«¯å¯¹åºæ¥å£æ¯æJSONPï¼JSON with paddingï¼åè®®ï¼æ以æ¯éè¦åæ¹çº¦å®å¥½ï¼æ以æµè§å¨è®¤ä¸ºè¿æ¯å®å
¨çã
- ä¼ç¹æ¯å ¼ä»»IEï¼å®ç°è·¨åã
- 缺ç¹æ¯ä¸è½æ§å¶è¯·æ±è¿ç¨ï¼ä»
æ¯æGETæ¹å¼è¯·æ±ãå 为åªæ¯ä¸ä¸ª
<script>
æ ç¾ï¼æµè§å¨èªå¨åèµ·çèµæºè¯·æ±ã
JSONPï¼JSON with Paddingï¼æ¯JSONçä¸ç§â使ç¨æ¨¡å¼âï¼æ¯ä¸ç§éå®æ¹çåè®®ï¼ç¨äºè§£å³æµè§å¨çè·¨åæ°æ®è®¿é®çé®é¢ã
ð¢åç«¯å ·ä½å®ç°è¿ç¨ï¼
- 1ãç³æä¸ä¸ªå ¨å±çåè°å½æ°âgetDataâæ¥æ¥æ¶æ°æ®ã
- 2ãå¨æå建ä¸ä¸ª
<script>
æ ç¾ï¼src
为è¦è·¨åçAPIå°åï¼URLä¸å¸¦ä¸åè°åæ°âcallback=getDataâã - 3ãæå¡ç«¯æ¶å°è¯·æ±åï¼å¨æçæä¸ä¸ªèæ¬ï¼èæ¬å
容æ¯ä¸ä¸ªå符串ï¼ç±åè°+è¿åçæ°æ®ææï¼â
getData('data')
âã - 4ãæ¬å°æ§è¡è¿ç¨èæ¬ï¼åè°å½æ°âgetDataâè¿è¡ï¼å°±å¾å°äºæ³è¦çæ°æ®ã
<script src="http:www.thrid.com/cors/api?q=key&callback=back"></script><script> function back(data) { console.log(data); }</script>
JSONPçå®ç°ï¼
function jsonp(url, args, cbName) { return new Promise((resolve, reject) => { const ele = document.createElement('script'); window[cbName] = (data) => { resolve(data); document.body.removeChild(ele); } args = { ...args, callback: cbName }; ele.src = `${url}?${Object.keys(args).map(k => `${k}=${args[k]}`).join('&')}`; document.body.appendChild(ele); });}//使ç¨ï¼api为360çå
¬å¼æ¥å£jsonp('https://sug.so.360.cn/suggest', { format: 'jsonp', word: 'china' }, 'search') .then(function (data) { console.log(data) });
2.2ãCORSè·¨å
CORSæ¯ä»ä¹ï¼ââ è·¨åèµæºå ±äº« ï¼cross-origin resource sharingï¼ï¼è®©AJAXå¯ä»¥è·¨å访é®æ°æ®ãè¿æ¯ä¸ºäºæ»¡è¶³è·¨å请æ±çéæ±ï¼W3Cæ°å¢å çç¹æ§ï¼éè¦æå¡ç«¯çæ¯æï¼ä¸æ¯æIE8/9ãæ ¹æ®è¯·æ±æ¹å¼ï¼æµè§å¨å°CORSå为两ç§æ åµï¼
- ç®å请æ±ï¼å®å ¨è¯·æ±ï¼ï¼åªæ¯æGETãPOSTãHEADï¼Headeråªæ¯æé¨åå段ã
- å¤æ请æ±ï¼å ¶ä»è¯·æ±ï¼ï¼ç®å请æ±ä»¥å¤çå ¶ä»è·¨å请æ±ã
ðµç®å请æ±
åºæ¬åçå°±æ¯å¨è¯·æ±å¤´å å ¥ä¸ä¸ªèº«ä»½æ¥æºæ è¯ï¼æå¡ç«¯æ ¹æ®è¿ä¸ªæ è¯æ¥å¤çæ¯å¦å 许访é®ï¼å¦æå 许åç»ä¸ä¸ªå 许çæ 记并è¿åååºã
- åªæ¯æGETãPOSTãHEADã
- header ââ æ们ä»
è½è®¾ç½®åºç¡çå®å
¨å段ï¼
- Accept
- Accept-Language
- Content-Language
- Content-Type çå¼ä¸º application/x-www-form-urlencodedï¼multipart/form-data æ text/plainã
ð¢å ·ä½è¿ç¨æ¯è¾ç®åï¼å端åªè¦å¨Headerå å ¥âOriginâå³å¯ï¼
- 请æ±å¤´Headerå å
¥è¦è·¨åçæºï¼
origin:http://www.main.com
GET /api HTTP/1.1Origin: http://www.main.com //æ¬æ¬¡è¯·æ±æ¥èªåªä¸ªæºHost: http://www.third.com //请æ±ç第ä¸æ¹APIAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
- æå¡ç«¯æ¶å°è¯·æ±åæ£æ¥Originï¼å¦æåæ请æ±åæ£å¸¸ååºï¼åæ¶å¨ååºçHeaderä¸å å ¥ç¹æ®çâAccess-Control-Allow-Originâå段ï¼ç³ææ¯æçæºï¼ä¹å¯ä»¥ç¨â*â表示æ¯æä»»ä½æºè®¿é®ã
- æµè§å¨æ¶å°ååºåä¼æ£æ¥âAccess-Control-Allow-Originâï¼åå½åæºå¯¹æ¯ï¼å¦æä¸åæ³åä¼æ¥éââè·¨åã
Access-Control-Allow-Origin: http://www.main.com //请æ±å
许çæºAccess-Control-Allow-Credentials: true //æ¯å¦å
许cookieï¼corsé»è®¤ä¸åécookieï¼å¦æè¦åéï¼è¿éAJAXä¸è®¾ç½®withCredentialsAccess-Control-Expose-Headers: Content-Length,API-Key //å¦æ客æ·ç«¯æ³è¦è®¿é®å
¶ä»éå®å
¨å段ï¼åéè¦æå¡ç«¯æç¡®å®ä¹åªäºHeaderå段æ´é²åºæ¥Content-Type: text/html; charset=utf-8
ð å¤æ请æ±
ä¸æ¯ç®å请æ±çé½ç§°ä¸ºå¤æ请æ±ï¼éç®å请æ±ï¼ï¼å¦è¯·æ±æ¹æ³æ¯PUTãDELETEï¼æContent-Type=application/json
ãç¸æ¯äºç®å请æ±ï¼å¤æ请æ±å¤äºä¸æ¬¡é¢è¯·æ±ã
é¢è¯·æ±ï¼
- æ£å¼åé请æ±åï¼æµè§å¨ä¼èªå¨åéä¸ä¸ªé¢è¯·æ±ï¼é®é®æå¡ç«¯æ¯å¦å 许æ¬æ¬¡è¯·æ±ï¼å¦æååºå 许ææ£å¼åé请æ±ï¼åé¢å°±åç®å请æ±ç¸åäºã
- é¢è¯·æ±åå
¶ååºé½æ²¡æbodyï¼éç¨
OPTIONS
æ¹æ³ã
03ãè·¨åå°ç»
å 为åæºæ¯æµè§å¨çéå¶ï¼è·¨åçæ¹æ³æ éå°±æ¯ç»è¿ï¼æéç¨CORSã
è·¨åæ¹æ¡ | åºæ¬åç | æ¯å¦éè¦æå¡ç«¯æ¯æ |
---|---|---|
JSONP | åå©<script> æ ç¾çsrc ï¼å ä¸ä¸ä¸ªå
¨å±åè°å½æ°æ¥æ¶æ°æ® |
ð éè¦æå¡ç«¯æ¯æJSONPåè®® |
CORS | W3Cæ åæ¯æçè·¨åæ¹å¼ï¼è¯·æ±å¤´æ·»å Origin å段 |
ð éè¦æå¡ç«¯æ¯æ |
WebSocket | WebSocketå¯ä»¥å®ç°æµè§å¨ä¸æå¡ç«¯çååéä¿¡ï¼æ²¡æè·¨åçå°æãæ¨è第ä¸æ¹åº Socket.ioï¼å¯ä»¥å¾æ¹ä¾¿ç建ç«ä¸æå¡ç«¯çSocketéä¿¡ã | ð éè¦æå¡ç«¯æ¯æï¼æ¯æWebSocket |
iframe+postMessage | 使ç¨window.postMessage() æ¥å®ç°çªå£ä¹é´çéä¿¡ |
ðµä¸éæå¡ç«¯å¤çï¼å®¢æ·ç«¯ç»è¿ |
æå¡ç«¯ä»£ç | ç±èªå·±çåæºæå¡ç«¯ä»£ç第ä¸æ¹çè¯·æ± | ð éè¦æå¡ç«¯æ¯æï¼ä»£çè¯·æ± |
nginxåå代ç | åçåæå¡ç«¯ä»£çä¸æ ·ï¼ç¨nginxé ç½®ä¸ä¸ªä»£çæå¡ | ðµä¸éè¦æå¡ç«¯ä¿®æ¹ä»£ç ï¼énginxæ¯æ |
åèèµæ
- Fetchï¼è·¨æºè¯·æ±
- ä¹ç§è·¨åæ¹å¼å®ç°åçï¼å®æ´çï¼
- ææ7大跨å解å³æ¹æ³åçç»æ10å¼ å¾ï¼åæå¾è§£ï¼
©ï¸çæç³æï¼çæææ@å®æ¨å¤ï¼æ¬æå å®¹ä» ä¾å¦ä¹ ï¼æ¬¢è¿ææ£ã交æµï¼è½¬è½½è¯·æ³¨æåºå¤ï¼åæç¼è¾å°å-è¯é