搜尋
首頁web前端js教程js中跨域的方法

js中跨域的方法

Dec 09, 2017 pm 04:58 PM
javascript方法

在製作oneday-music-player的時候要使用ajax向百度音樂的api發送請求,然後出現了XMLHttpRequest cannot load 'http://....' . No 'Access-Control-Allow-Origin' header is present on the request resource. Origin 'http://....' is therefore not allowed access,經過搜尋發現是受到了同源策略的影響而導致的跨域問題,所以學習一下關於跨域的知識點。

同源策略

同源策略限制從一個來源載入的文件或腳本與另一個來源的文件或腳本互動的方式,是隔離潛在惡意檔案的重要安全機制。

兩個頁面擁有相同的協定、連接埠(如果指定)和網域時,可以說兩個頁面是同源的。

下表是相對於<span style="font-size: 14px;">http://store.company.com/dir/page.html</span>同源檢測的範例:

🜎. /dir/inner/other.htmlhttps://store.company.com/secure.htmlhttp不同連接埠( 81和80)不同域名()

而如果非同源,則有三種行為會受到限制:

    而如果非同源,則有三種行為會受到限制:
  • 而如果非同源,則有三種行為會受到限制:

  • 而如果非同源,則有三種行為會受到限制:
  • 而如果非同源,則有三種行為會受到限制:

  • 而如果非同源,則有三種行為會受到限制:
  • 而如果非同源,則有三種行為會受到限制:

<span style="font-size: 14px;"></span>規避同源策略(跨域)

<span style="font-size: 14px;"></span>Cookie<span style="font-size: 14px;"></span>document.domain網頁但是,兩個網頁一級網域相同,只是二級網域​​不同,瀏覽器允許透過

document.domain<span style="font-size: 14px;">共享Cookie</span>/例如,假設文件中的一個腳本在

:/ /store.company.com/dir/page.html<span style="font-size: 14px;"></span>執行以下語句:<span style="font-size: 14px;"></span>

<span style="font-size: 14px;">document.domain = "company.com"<br></span>
此時,<span style="font-size: 14px;">http://news.company.com/dir/other.html</span>
http://store.company.com/dir/other.html<span style="font-size: 14px;"></span>就可以透過

document.cookie<span style="font-size: 14px;"></span>

來設定或取得Cookie,也就是共用Cookie。

<span style="font-size: 14px;"></span>

但是這種方法適用於Cookie和iframe窗口,LocalStorage和IndexDB無法透過這種方法來規避同源策略。

<span style="font-size: 14px;"></span>iframe<span style="font-size: 14px;"></span>如果兩個網頁不同來源,就無法拿到對方的DOM,典型的例子是<span style="font-size: 14px;">iframe</span>. ,如果和父視窗不同來源,則會報錯。 <span style="font-size: 14px;"></span>

此時如果兩個視窗一級網域相同,只是二級網域​​不同,那麼設定<span style="font-size: 14px;"></span>document.domain<span style="font-size: 14px;"></span>屬性,就可以規避同源策略。 <span style="font-size: 14px;"></span>

而對於完全不同來源的網站,目前有三種方法可以解決跨域視窗之間的通訊問題。 <span style="font-size: 14px;"></span>

  • 片段識別符(fragment identifier)<span style="font-size: 14px;"></span>

  • window.name<span style="font-size: 14px;"></span>

  • 片段標識符
  • 片段標識符(fragment identifier)指的是URL的#後面的部分,即

http://store.company.com/dir/other.html#fragment

<span style="font-size: 14px;"></span>的

#rag

#rag (location.hash),如果只改變片段標識符,頁面不會重新刷新。 <span style="font-size: 14px;"></span>父視窗可以把訊息寫入子視窗的片段標識符,子視窗透過監聽<span style="font-size: 14px;"></span>hashchange<span style="font-size: 14px;"></span>事件得到通知。 <span style="font-size: 14px;"></span>

window.name<span style="font-size: 14px;"></span><span style="font-size: 14px;">每個iframe都有包裹它的window,這個window是top window的子窗戶,所以自然有</span>window.name

<span style="font-size: 14px;"></span>window.name

名字,這個屬性的最大特點是,無論是否同源,只要在同一個視窗裡,視窗內所有頁面對window.name都有讀寫的權限。 <span style="font-size: 14px;"></span><span style="font-size: 14px;">window.name的值只能是字串的形式,這個字串的最大能允許2M左右甚至更大的一個容量,取決於不同的瀏覽器。 </span>

例如,想要在<span style="font-size: 14px;">http://example/a.html</span>中获取<span style="font-size: 14px;">http://company.com/data.html</span>中的数据,可以在a.html中使用一个隐藏的iframe,将iframe的src首先设置为<span style="font-size: 14px;">http://company.com/data.html</span>,将其window.name设置为所需的数据内容,随后再将这个iframe的src设置为跟a.html页面同一个域的一个页面,不然a.html获取不到该iframe的window.name

<span style="font-size: 14px;">window.postMessage</span>

这是html5中新引入的一个API,可以使用它向其它的window对象发送消息,无论这个window对象属于同源还是不同源。

例如,父窗口<span style="font-size: 14px;">http://example/a.html</span>向子窗口<span style="font-size: 14px;">http://company.com/data.html</span>发送消息:

<span style="font-size: 14px;">var newWin = window.open('http://company.com/data.html', 'title')<br>newWin.postMessage('Hello World!'. 'http://company.com/data.html')<br></span>

<span style="font-size: 14px;">window.postMessage</span>方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源,即<span style="font-size: 14px;">协议</span>+<span style="font-size: 14px;">端口</span>+<span style="font-size: 14px;">域名</span>,也可以设置为<span style="font-size: 14px;">*</span>,表示不限制域名。

子窗口向父窗口发送消息的写法类似:

<span style="font-size: 14px;">window.opener.postMessage('Nice to see you', 'http://example/a.html')<br></span>

子窗口和父窗口都可以通过<span style="font-size: 14px;">message</span>时间,监听对方的消息。

<span style="font-size: 14px;">window.addEventListener('message', function(e) {<br>    // ...<br>}, false)<br></span>

<span style="font-size: 14px;">message</span>事件的事件对象<span style="font-size: 14px;">event</span>有以下三个属性:

  • event.source: 发送消息的窗口

  • event.origin: 消息发向的网址(可以限制目标网址)

  • event.data: 消息内容

通过<span style="font-size: 14px;">window.postMessage</span>,也可以读写其他窗口的<span style="font-size: 14px;">localStorage</span>

AJAX

同源策略规定,AJAX请求只能发给同源的网址,否则就报错,但是有三种方法可以规避这个限定:

  • JSONP

  • WebSocket

  • CORS

JSONP

JSONP是服务器与客户端跨源通信的常用方法。基本思想是利用<span style="font-size: 14px;"><script></script></span>请求脚本能够跨域访问的特性,先定义了一个回调方法,然后将其作为url参数的一部分发送到服务端,服务端通过字符串拼接的方式将数据包裹在回调方法中,再返回回来。

<span style="font-size: 14px;">// 网页动态插入`<script>`元素<br/>function addScriptTag(src) {<br/>    var script = document.createElement("script")<br/>    script.setAttribute("type", "text/javascript")<br/>    srcipt.src = src<br/>    document.body.appendChild(script)<br/>}<br/><br/>window.onload = function() {<br/>    addScriptTag(&#39;http://example.com/ip?callback=foo&#39;)<br/>}<br/><br/>function foo(data) {<br/>    // ...<br/>}<br/></script></span>

WebSocket

WebSocket是一种通信协议,使用<span style="font-size: 14px;">ws://</span>(非加密)和<span style="font-size: 14px;">wss://</span>(加密)作为协议前缀。该协议不实行同源政策,只要服务支持,就可以通过它进行跨源通信。

浏览器发出的WebSocket请求的头信息中含有<span style="font-size: 14px;">Origin</span>字段,表示该请求的请求源,即发自哪个域名。(加入白名单)

CORS

跨域资源共享(Cross-Origin Resource Sharing,CORS)是一种使用额外的HTTP头来使一个用户代理从一个不同于当前站点(域)的服务器获取指定的资源的机制。用户代理使用跨域HTTP请求来获取与当前文档不同域、不用协议或端口的资源。

出于安全考虑,浏览器会限制从脚本内发起的跨域HTTP请求。而跨域资源共享(CORS)机制允许web应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在API容器中(例如<span style="font-size: 14px;">XMLHttpRequest</span><span style="font-size: 14px;">Fetch</span>)使用CORS,以降低跨域HTTP请求所带来的风险。

跨域资源共享标准允许在下列场景中使用跨域HTTP请求:

  • 由XMLHttpRequest或Fetch发起的跨域HTTP请求;

  • web字体(CSS中通过<span style="font-size: 14px;">@font-face</span>使用跨域字体资源),因此,网站就可以发布TrueType字体资源,并只允许已授权网站进行跨站调用;

  • WebGL贴图;

  • 使用drawImage将Images/video画面绘制到canvas;

  • 样式表(使用CSSOM);

  • Scripts(未处理的异常)。

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)

只要同时满足以下两大条件,就属于简单请求:

1 请求方法是以下三种方法之一:

<span style="font-size: 14px;">- HEAD<br>- GET<br>- POST<br></span>

2 HTTP的头信息不超出以下几种字段:

<span style="font-size: 14px;">- Accept<br>- Accept-Language<br>- Content-Language<br>- Last-Event-ID<br>- Content-Type:(只限三个值:application/x-www-form-urlencoded、multipart/from-data、text/plain)<br></span>

只要不同时满足上面两个条件,就属于非简单请求

简单请求

对于简单请求,浏览器会在请求头部增加一个<span style="font-size: 14px;">Origin</span>字段。这个字段用来说明本次请求来自哪个源(协议+域名+端口)。服务器根据这个值决定是否同意这次请求。

如果<span style="font-size: 14px;">Origin</span>指定的源不在许可范围内,服务器会返回一个正常的HTTP回应。而这个回应的头信息不包含<span style="font-size: 14px;">Access-Control-Allow-Origin</span>字段,从而会抛出错误被<span style="font-size: 14px;">XMLHttpRequest</span><span style="font-size: 14px;">onerror</span>函数捕获,(回应的状态码有可能是200)。

如果<span style="font-size: 14px;">Origin</span>指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段

<span style="font-size: 14px;">Access-Control-Allow-Origin: ...<br>Access-Control-Allow-Credentials: true<br>Access-Control-Expose-Headers: callback<br>Content-Type: text/html; charset=utf-8<br></span>
  • <span style="font-size: 14px;">Access-Control-Allow-Origin</span>: 必须。值要么是请求时<span style="font-size: 14px;">Origin</span>的值,要么是'*'

  • <span style="font-size: 14px;">Access-Control-Allow-Credentials</span>: 可选。布尔值,决定是否允许发送Cookie,不需要则删除该字段。

  • <span style="font-size: 14px;">Access-Control-Expose-Headers</span>: 可选。CORS请求时,<span style="font-size: 14px;">XMLHttpRequest</span>对象的 <span style="font-size: 14px;">getResponseHeader()</span>方法只能拿到6个基本字段:<span style="font-size: 14px;">Cache-Control</span><span style="font-size: 14px;">Content-Language</span><span style="font-size: 14px;">Content-Type</span><span style="font-size: 14px;">Expires</span><span style="font-size: 14px;">Last-Modified</span><span style="font-size: 14px;">Pragma</span>。如果想拿到其他字段,就需要在<span style="font-size: 14px;">Access-Control-Expose-Header</span>里面指定。上面的例子指定为callback,则可以使用<span style="font-size: 14px;">getResponseHeader(callback)</span>获取callback字段的值。

CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发送到服务器,一方面要服务器同意,指定<span style="font-size: 14px;">Access-Control-Allow-Credentials</span>字段,另一方面,开发者需要在AJAX请求中设置<span style="font-size: 14px;">withCredentials</span>属性:

<span style="font-size: 14px;">var xhr = new XMLHttpRequest()<br>xhr.withCredentials = true<br></span>

否则,即使服务器同意发送Cookie,浏览器也不会发送。

需要注意的是,如果要发送Cookie,<span style="font-size: 14px;">Access-Control-Allow-Origin</span>就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源策略,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且跨域的原网页中的<span style="font-size: 14px;">document.cookie</span>操作也无法获取嗷服务器域名下的Cookie。

非简单请求

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是<span style="font-size: 14px;">PUT</span><span style="font-size: 14px;">DELETE</span>,或者<span style="font-size: 14px;">Content-Type</span>字段的类型是<span style="font-size: 14px;">application/json</span>

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为“预检”请求。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP操作和头信息字段。只有得到肯定答复,浏览器才会发出正式的<span style="font-size: 14px;">XMLHttpRequest</span>请求,否则就报错。

“预检”请求用请求方法是<span style="font-size: 14px;">OPTIONS</span>,表示这个请求是用来询问的。头信息里面,关键字段是<span style="font-size: 14px;">Origin</span>,表示请求来自哪个源。

还有以下两个特殊字段:

  • <span style="font-size: 14px;">Access-Control-Request-Method</span>: 必须。列出非简单请求的请求类型

  • <span style="font-size: 14px;">Access-Control-Request-Headers</span>: 非简单请求额外携带的头信息字段。

服务器返回的响应:

<span style="font-size: 14px;">Access-Control-Allow-Methods: ...<br>Access-Control-Expose-Headers: callback<br>Access-Control-Allow-Credentials: true<br>Access-Control-Max-Age: 1728000<br></span>
  • Access-Control-Allow-Methods: 必须。逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。为了避免多次“预检”行为。

  • Access-Control-Expose-Headers: 如果瀏覽器請求包含<span style="font-size: 14px;">Access-Control-Request-Headers</span>字段,則<span style="font-size: 14px;">. 。它也是一個逗號分隔的字串,表示伺服器支援的所有頭資訊字段,不限於瀏覽器在"預檢"中請求的字段。 </span><span style="font-size: 14px;"></span>

  • Access-Control-Allow-Credentials: 與簡單請求時的含義相同。
  • <span style="font-size: 14px;"></span>

  • Access-Control-Max-Age: 本次預檢請求的有效期限。
  • <span style="font-size: 14px;"></span>

  • CORS與JSONP的比較

<span style="font-size: 14px;"></span>CORS與JSONP的使用目的相同,但是比JSONP更強大。

<span style="font-size: 14px;"></span>JSONP只支援

GET<span style="font-size: 14px;">請求,CORS支援所有類型的HTTP請求。 JSONP的優勢在於支援老式瀏覽器,以及可以向不支援CORS的網站請求資料。 </span><span style="font-size: 14px;"></span>相關建議:

<span style="font-size: 14px;"></span>

用Js實現懶載與跨域的實作步驟

原因 <span style="font-size: 14px;"></span> <span style="font-size: 14px;"></span>http://store.company.com/dir2/other.html
<span style="font-size: 14px;"></span>成功 <span style="font-size: 14px;"></span>
<span style="font-size: 14px;"></span> https
)<span style="font-size: 14px;"></span> <span style="font-size: 14px;"></span>http://store.company.com:81/dir/ <span style="font-size: 14px;"></span><span style="font-size: 14px;"></span>http://news.company.com/dir/other.html<span style="font-size: 14px;"></span><span style="font-size: 14px;"></span>失敗<span style="font-size: 14px;"></span>
news<span style="font-size: 14px;"></span>和 store<span style="font-size: 14px;"></span> <span style="font-size: 14px;"></span>

以上是js中跨域的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),