您好,登錄后才能下訂單哦!
這篇文章主要介紹怎么解決js跨域問題,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
Js跨域問題是web開發人員最常碰到的一個問題之一。所謂js跨域問題,是指在一個域下的頁面中通過js訪問另一個不同域下的數據對象,出于安全性考 慮,幾乎所有瀏覽器都不允許這種跨域訪問,這就導致在一些ajax應用中,使用跨域的web service會成為一個問題。 解決js跨域問題,目前在客戶端和服務端都有一些現成的解決方案,但這些方案并不能解決所有問題。下面我們先來看下有哪些常用的解決方案,并針對空間產品 對跨域問題的需求給出一個space自己的解決方案,希望能對其他產品組有借鑒意義。
客戶端解決方案
如何在客戶端解決js跨域問題幾乎是所有web開發人員會首先考慮的。目前最常用的方法有2種:設置document.domain、通過script 標簽加載。
設置document.domain
采用這種方法的前提是跨域請求涉及的兩個頁面必須屬于一個基礎域(例如都是xxx.com,或是xxx.com.cn),使用同一協議(例如都是 http)和同一端口(例如都是80)。例如,aaa.xxx.com里面的一個頁面需要調用bbb.xxx.com里的一個對象,則將兩個頁面的 document.domain都設置為xxx.com,就可以實現跨域調用了。 另外,需要注意的是,這種方式只能用在父、子頁面之中,即只有在用iframe進行數據訪問時才有用。
通過script標簽加載
對于瀏覽器來說,script標簽的src屬性所指向資源就跟img標簽的src屬性所指向的資源一樣,都是一個靜態資源,瀏覽器會在適當的時候自動去加 載這些資源,而不會出現所謂的跨域問題。這樣我們就可以通過該屬性將要訪問的數據對象引用進當前頁面而繞過js跨域問題。 例如,在space的我的空間項目中,需要在hi域下管理中心頁面中隨機推薦幾個熱門模塊給用戶,由于熱門模塊的相關信息都在act域下的php模塊中維 護,如果直接在hi域下通過ajax請求去獲取act域下的推薦模塊列表相關信息就出現js跨域問題。解決這個問題的最簡單方法就是,在hi域下通過 script標簽去訪問act域提供的這個http接口:
<script type=”text/javascript” src=http://www.2cto.com/kf/201109/”http://act.hi.baidu.com/widget/recommend”><script>
當然,前提是act域的這個http接口必須是返回一段js腳本,如一個json對象數組定義的腳本:
modlist = [
{“modname” : “mod1”, “usernum” : 200, “url” : ” /widget/info/1”},
{“modname” : ”mod2”, “usernum” : 300, ”url” : ” /widget/info/2”},
…
];
但script標簽也有一定的局限性,并不能解決所有js跨域問題。script標簽的src屬性值不能動態改變以滿足在不同條件下獲取不同數據的需求, 更重要的是,不能通過這種方式正確訪問以xml內容方式組織的數據。
服務端解決方案
從上面的說明可以看到,客戶端的解決方案局限性太大,而且對于ajax跨域請求,無論兩個域是否屬于同個基礎域,都無法在客戶端加以解決。也就是說,如果 我們要想在ajax請求中訪問其他域下的數據,就只能通過服務端進行處理了。 服務端的解決方案的基本原理就是,由客戶端將請求發給本域服務器,再由本域服務器的代理來請求數據并將響應返回給客戶端。 最常用的服務器解決方案就是利用web服務器本身提供的proxy功能,如apache和lighttpd的mod_proxy模塊。在百度內 部,transmit的分流功能也可以解決部分跨域問題。但這些方法都有一定的局限性,鑒于安全性等問題的考慮,space這邊最后開發了一個專門用于處 理跨域請求代理服務的spproxy模塊,用于徹底解決js跨域問題。 下面我們將以空間的開放平臺為例,簡單介紹下如何通過apache的mod_proxy、transmit的分流以及space的spproxy模塊來解 決該跨域問題,并簡單介紹下spproxy的一些特性、缺點及下一步的改進計劃。 空間在展現每個UWA開放模塊之前都必須請求該模塊的xml源代碼以進行解析,每個模塊的源代碼文件都是存放在act域下的/ow/uwa目錄下,那么在 用戶空間首頁(hi域)中請求該xml文件時就會存在js跨域問題。要解決該問題,只能讓js向hi域的web服務器請求xml文件,而hi域web服務 器則通過一定的代理機制(如mod_proxy、transmit分流、spproxy)向act域的web服務器請求文件。
利用apache的mod_proxy模塊
如果apache是2.0系列版本,則可以通過在httpd.conf文件中增加以下配置加以解決:
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /ow/uwa http://act.hi.baidu.com/ow/uwa
其中,ProxyRequests 指令關閉了mod_proxy的正向代理功能而啟用反向代理功能,Proxy指令使得該配置對所有訪問生效,ProxyPass指令使得對本域的/ow /uwa目錄下的任何資源的訪問都會在內部被轉換為一個對act.hi.baidu.com域下的/ow/uwa目錄下對應資源的代理請求。 這樣,js就可以直接通過訪問http://hi.baidu.com/ow/uwa/0/1/0/10001.xml 獲取位于act域下的/ow/uwa/0/1/0/目錄下的10001.xml文件。
如果apache是經過百度各產品線修改過的1.3版本,則需要mod_proxy和mod_rewrite模塊一起配合來達到同樣的目的。首先需要在 httpd.conf中增加以下Location指令:
<Location /ow/uwa>
SetHandler proxy-server
order allow,deny
Allow from all
</Location>
這樣,對于本域下的/ow/uwa目錄下的任何資源的訪問都會首先由proxy-server這個handler(mod_proxy模塊內部定義的一個 handler)來處理,但光有這段配置還不行,因為還不proxy-server還不知道應該怎么處理,僅僅知道需要自己處理而已。這時還需要在配置段中增加一個rewrite規則:
RewriteRule ^/ow/uwa/(.*)$ http://act.hi.baidu.com/ow/uwa/$1?%{QUERY_STRING} [P,L]
Rewrite規則最后的[P,L]表明該rewrite是通過mod_proxy代理過去,而不是通過外部重定向過去。如果去掉P標志,即采用以下 rewrite規則:
RewriteRule ^/ow/uwa/(.*)$ http://act.hi.baidu.com/ow/uwa/$1?%{QUERY_STRING} [L]
則響應返回給客戶端時標明的資源uri將是重定向后的uri,在我們的例子中就是act.hi.baidu.com域的uri,則瀏覽器仍然會出現 js跨 域問題。 以上只是對apache的proxy功能的簡單應用,更好更強大的介紹可以參考資料【1】和【2】。 Mod_proxy雖然強大,但我們并沒有用它來解決跨域問題。首先,要使用它必須要求我們的每臺前端機器都能夠訪問外網,否則我們就只能將請求代理到其 中一臺前端機器上(通過機器名做內網域名進行rewrite或代理),而這顯然是不可取的,因為我們的一個域名通常由很多前端機器組成,只代理到其中一臺 機器會導致該機器壓力與其他機器相比很不均衡,甚至撐不住壓力,而給所有前端機器都加訪問外網權限又可能會存在一些安全性策略問題(具體原因不清楚,但 op和sa顯然是不會贊同這種做法)。其次,由于apache本身并沒有很好的防ddos***機制,一旦有人通過代理去***目標域(比如說我們的競爭對手 的網站),則在目標域的web服務器上看來,***者就成了我們了,這樣的事情發生時,我們就百口莫辯,跳進黃河也洗不清了。
以上是“怎么解決js跨域問題”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。