摘要:跨域完全講解今天在慕課網上學習了跨域完全講解我在收集面試題的時候其實就已經有過跨域的問題的了,當時候知道了為什么會存在跨域,以及跨域解決的方案有哪些,今天隨著課程的學習,又加深了跨域的理解,以此記錄下來。
AJAX跨域完全講解
今天在慕課網上學習了AJAX跨域完全講解:https://www.imooc.com/learn/947
我在收集AJAX面試題的時候其實就已經有過AJAX跨域的問題的了,當時候知道了為什么會存在跨域,以及跨域解決的方案有哪些,今天隨著課程的學習,又加深了AJAX跨域的理解,以此記錄下來。
為什么會發生產生跨域問題?上面的圖也很清晰了,因為瀏覽器為了安全(同源),本身就限制了。
當我們發送XMLHttpRequest請求的時候,如果請求的是別的域(主機域名、端口)不同時,那么就會產生跨域問題(客戶端無法獲取服務端返回的數據)
值得注意的是:跨域的問題是發生在XMLHttpRequest請求的,也就是說,不是XMLHttpRequest請求是不會有跨域問題的
舉個很簡單的例子:在編寫網頁的時候,,URL不是本域的還是可以正常獲取該圖片的
解決跨域問題的思路明顯地,跨域的問題是由于瀏覽器限制的,是XMLHttpRequest才會發生的,那么我們可以以這個思路去找找解決思路:
對于瀏覽器的問題,可以使用相關的參數進行啟動瀏覽器,是可以解決跨域的問題,但是通用性是極低的,了解即可。
JSONP解決跨域JSONP是JSON使用的一種補充方式,不是官方的協議。JSONP是一種解決跨域問題的一種協議
JSONP這種解決方案其實現在已經很少用了(復雜一點,需要修改后臺代碼),但我們可以適當了解一下。
使用步驟在后端增加一個控制器,繼承AbstractJsonpResponseBodyAdvice類,完整代碼如下:
@ControllerAdvice public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice { public JsonpAdvice() { // TODO Auto-generated constructor stub super("callback2"); } }
前端ajax請求:
// 服務器返回的結果 var result; $.ajax({ url: base +"/get1", dataType: "jsonp", jsonp: "callback2", //是否需要緩存,如果這里沒有配置緩存,那么請求的URL還會有一個參數 cache:true, success: function(json){ result = json; } });
注意的是,前端AJAX的jsonp: "callback2",要和我們的Controllersuper("callback2");是一致的,不然是不會有效的。
JSONP原理是動態創建script來進行請求的:
JSONP的弊端:
要對服務器的代碼進行改動
只支持GET方法(原理是動態創建script來進行請求的)
發送的不是XMLHttpRequest請求(XMLHttpRequest請求有很多好用的特性)
參考資料:
https://www.cnblogs.com/blacksonny/p/5846411.html
CORS解決跨域問題CORS解決跨域問題(也就是我們服務端被調用方解決跨域的思路)
對于CORS是怎么理解的,我就直接摘抄一下:https://segmentfault.com/a/1190000012469713#articleHeader8的了。
在Java中,我們寫下面這個過濾器,就可以完全解決跨域的問題了:
package com.imooc; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.tomcat.util.buf.StringUtils; public class CrosFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub HttpServletResponse res = (HttpServletResponse) response; HttpServletRequest req = (HttpServletRequest) request; //帶cookie的時候,origin必須是全匹配,不能使用* String origin = req.getHeader("Origin"); if (!org.springframework.util.StringUtils.isEmpty(origin)) { res.addHeader("Access-Control-Allow-Origin", origin); } res.addHeader("Access-Control-Allow-Methods", "*"); // 支持所有自定義頭和預檢命令(非簡單請求會有預檢命令) String headers = req.getHeader("Access-Control-Request-Headers"); if (!org.springframework.util.StringUtils.isEmpty(headers)) { res.addHeader("Access-Control-Allow-Headers", headers); } res.addHeader("Access-Control-Max-Age", "3600"); // enable cookie res.addHeader("Access-Control-Allow-Credentials", "true"); chain.doFilter(request, response); } @Override public void destroy() { // TODO Auto-generated method stub } }
上面提到了非簡單請求,那什么是非簡單請求呢,可以看下面的圖:
非簡單請求會發出一個預檢命令的(當然了,我們上面的Filter已經解決預檢命令的問題了):
Spring框架解決如果使用的是Spring框架的話,那就只需要一個注解就能夠解決跨域的問題了:@CrossOrigin
HTTP服務器層我們在的商用開發中,一般請求的過程是這樣的:瀏覽器->HTTP服務器(Nginx,Apache)->應用服務器(Tomcat,Weblogic)
上面編寫的Filter、Spring框架都是在應用服務器上解決的,我們也是可以通過HTTP服務器(Nginx,Apache)來進行解決跨域問題的!
Nginx我用過,Apache我倒是還沒用過,下面就簡單記錄了Nginx和Apache是如何配置的:
Nginx配置:
Apache配置:
代理解決跨域問題在之前的圖我們已經看到了,解決跨域的問題可以在“調用方”中來進行解決。
“調用方”解決跨域的問題是這個思路的:讓發送出去的請求代理成是本域的
舉個例子:
www.zhongfucheng.top是調用方 www.zhongfucheng.site是被調用方
它倆是不同域的,但我們可以在nginx或Apache上進行配置代理:將被調用方www.zhongfucheng.site映射成別的路徑
比如,像下面的圖,將8080端口的映射成了ajaxServer,當調用方訪問ajaxServer路徑時,這樣的方法在外部看起來就不像是跨域了,像是訪問本地(8081端口),但實際訪問別的域(8080端口)
總結令我感到最簡單的是通過Spring的注解就可以解決跨域的問題了,JSONP的方式已經是很少用的了,因為存在一定的弊端,但了解一下也無妨,畢竟可能面試的時候會問到。當沒有用任何框架的時候,寫Filter也不麻煩,也只是配置了一下HTTP頭信息而已。如果使用Nginx、Apache時,也可以用代理或者配置HTTP頭信息都可以解決。看完之后,有沒有覺得跨域問題就迎刃而解了。
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章的同學,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93074.html
摘要:跨域完全講解今天在慕課網上學習了跨域完全講解我在收集面試題的時候其實就已經有過跨域的問題的了,當時候知道了為什么會存在跨域,以及跨域解決的方案有哪些,今天隨著課程的學習,又加深了跨域的理解,以此記錄下來。 AJAX跨域完全講解 今天在慕課網上學習了AJAX跨域完全講解:https://www.imooc.com/learn/947 我在收集AJAX面試題的時候其實就已經有過AJAX跨域...
摘要:時間年月日星期三說明本文部分內容均來自慕課網。當預檢請求通過的時候,才發送真正的請求。 時間:2018年04月18日星期三說明:本文部分內容均來自慕課網。@慕課網:https://www.imooc.com教學源碼:https://github.com/zccodere/s...學習源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介...
摘要:結果如圖所示,第二個由于跨域仍然報錯,第三個則正常輸出在中修改也可以通過向瀏覽器返回特定響應頭,告訴瀏覽器它是允許被跨域調用的,使用的添加和兩個字段,更新如下將的方法請求的接口改為,依次點擊,第二個已經可以正常輸出內容 總結自慕課網:ajax跨域完全講解,并且原視頻中后臺為JAVA,這里改成了Python。 什么是AJAX跨域 只要協議、域名、端口有任何一個不同,都被當作是不同的域,...
摘要:把數據包裹在一個客戶端聲明的本地的回調函數中,這樣可以動態加載一個跨域服務器數據。在本地聲明這個動態中的回調函數名稱,并且定義該函數,然后通過參數傳遞到服務器。 為什么要跨域 我們都知道在瀏覽器地址欄輸入地址的時候可以隨便訪問一個頁面,但是如果你在ajax請求中發出一個xhr請求那么因為瀏覽器安全策略只有同源的服務器才能處理。這就是同源策略 要求協議/域名/端口三者完全一致才能訪問 ...
閱讀 632·2021-11-22 15:32
閱讀 2720·2021-11-19 09:40
閱讀 2313·2021-11-17 09:33
閱讀 1263·2021-11-15 11:36
閱讀 1864·2021-10-11 10:59
閱讀 1475·2019-08-29 16:41
閱讀 1780·2019-08-29 13:45
閱讀 2150·2019-08-26 13:36