ajax跨域問題的解決方法:1、回應頭添加Header允許存取;2、jsonp只支援get請求不支援post請求;3、httpClient內部轉送;4、使用nginx搭建企業級介面網關方式。
相關免費學習推薦:ajax(視頻)
ajax跨域問題的解決方法:
解決方式1:回應頭新增Header允許存取
跨域資源共享(CORS)Cross-Origin Resource Sharing
這個跨域存取的解決方案的安全基礎是基於"JavaScript無法控制該HTTP頭"
#它需要透過目標網域傳回的HTTP頭來授權是否允許跨網域存取。
response.addHeader(‘Access-Control-Allow-Origin:*’);//允许所有来源访问 response.addHeader(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式
解決方法2:jsonp 只支援get請求不支援post請求
用法:①dataType改為jsonp ②jsonp : "jsonpCallback"— ———發送到後端實際為http://a.a.com/a/FromServlet?userName=644064&jsonpCallback=jQueryxxx ③後端取得get請求中的jsonpCallback ④建構回呼結構#rr#rrSON##re#reSON
reSONreSONreSON##r#r#r#r#r#w代碼原理
在同源策略下,在某個伺服器下的頁面是無法取得到該伺服器以外的資料的,即一般的ajax是不能進行跨網域請求的。但 img、iframe 、script等標籤是個例外,這些標籤可以透過src屬性請求到其他伺服器上的資料。利用3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤的開放策略,我們可以實現跨域請求數據,當然這需要伺服器端的配合。 Jquery中ajax的核心是透過 XmlHttpRequest取得非本頁內容,而jsonp的核心則是動態新增3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤來呼叫伺服器提供的 js腳本。
當我們正常地請求一個JSON資料的時候,服務端回傳的是一串JSON類型的數據,而我們使用JSONP模式來請求資料的時候服務端回傳的是一段可執行的JavaScript程式碼。因為jsonp 跨域的原理就是用的動態載入3f1c4e4b6b16bbbd69b2ee476dc4f83a的src ,所以我們只能把參數透過url的方式傳遞,所以jsonp的 type型別只能是get !
範例:
$.ajax({ type : "GET", async : false, url : "http://a.a.com/a/FromServlet?userName=644064", dataType : "jsonp",//数据类型为jsonp jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数 success : function(data) { alert(data["userName"]); }, error : function() { alert('fail'); } }); //后端 String jsonpCallback = request.getParameter("jsonpCallback"); //构造回调函数格式jsonpCallback(数据) resp.getWriter().println(jsonpCallback+"("+jsonObject.toJSONString()+")");
其實jquery 內部會轉換成
#http://192.168.10.46/demo/test.jsp?jsonpCallback=jQuery202003573935762227615_1Query202003573935762227615_140028 ##接著動態載入
$.ajax({ url: 'http://192.168.10.46/demo/test.jsp', //不同的域 type: 'GET', // jsonp模式只有GET 是合法的 data: { 'action': 'aaron' }, dataType: 'jsonp', // 数据类型 jsonp: 'jsonpCallback', // 指定回调函数名,与服务器端接收的一致,并回传回来 })
然後後端就會執行jsonpCallback(傳遞參數),把資料用實參的形式送出。
使用JSONP 模式來請求資料的整個流程:客戶端發送一個請求,規定一個可執行的函數名稱(這裡就是jQuery做了封裝的處理,自動幫你產生回呼函數並把資料取出來供success屬性方法來呼叫,而不是傳遞的一個回調句柄),伺服器端接受了這個jsonpCallback函數名,然後把資料透過實參的形式傳出去
#(在jquery在原始碼中, jsonp的實作方式是動態新增3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤來呼叫伺服器提供的js腳本。jquery 會在window物件中載入一個全域的函數,當3f1c4e4b6b16bbbd69b2ee476dc4f83a程式碼插入時函數執行,執行完畢後就3f1c4e4b6b16bbbd69b2ee476dc4f83a會被移除。同時jquery也對非跨域的請求進行了優化,如果這個請求是在同一個網域下那麼他就會像正常的Ajax請求一樣工作。)
解決方式3:httpClient內部轉送
實作原理很簡單,若想在B站點中透過Ajax造訪A站點取得結果,固然有ajax跨域問題,但在B站點中訪問B站點獲取結果,不存在跨域問題,這種方式實際上是在B站點中ajax請求訪問B站點的HttpClient,再通過HttpClient轉發請求獲取A站點的數據結果。但這種方式產生了兩次請求,效率低,但內部請求,抓包工具無法分析,安全。
<script type="text/javascript"src="http://192.168.10.46/demo/test.jsp?jsonpCallback= jQuery202003573935762227615_1402643146875&action=aaron"></script>
解決方式4:使用nginx建置企業級介面閘道方式
www.a.a.com不能直接要求www.b.b.com的內容,可以透過nginx,根據同域名,但項目名稱不同進行區分。什麼意思呢?這麼說可能有點抽象。假設我們公司網域名叫www.nginxtest.com
當我們需要訪問www.a.a.com透過www.nginxtest.com/A訪問,並透過nginx轉發到www.a.a.com
當我們需要訪問www.b.b.com透過www.nginxtest.com/B訪問,並透過nginx轉發到www.a.a.com
我們訪問公司的網域時,是"同源"的,只是項目名不同,此時項目名的作用只是為了區分,方便轉發。如果你還不理解的話,先看看我是怎麼進行設定的:
server { listen 80; server_name www.nginxtest.com; location /A { proxy_pass http://a.a.com:81; index index.html index.htm; } location /B { proxy_pass http://b.b.com:81; index index.html index.htm; } }
我们访问以www.nginxtest.com开头且端口为80的网址,nginx将会进行拦截匹配,若项目名为A,则分发到a.a.com:81。实际上就是通过"同源"的域名,不同的项目名进行区分,通过nginx拦截匹配,转发到对应的网址。整个过程,两次请求,第一次请求nginx服务器,第二次nginx服务器通过拦截匹配分发到对应的网址。
相关免费学习推荐:javascript(视频)
以上是ajax跨域問題如何解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!