-
總的來(lái)說(shuō), 跨域問(wèn)題有3個(gè)原因: ?瀏覽器的限制, 跨域, xhr(XMLHttpRequest) 請(qǐng)求; 這三個(gè)條件同時(shí)滿足才會(huì)產(chǎn)生跨域安全問(wèn)題
瀏覽器的限制
發(fā)生這個(gè)跨域問(wèn)題不是因?yàn)楹笈_(tái)不允許前臺(tái)調(diào)用, 真正的原因是瀏覽器出于安全考慮, 當(dāng)他發(fā)現(xiàn)你的請(qǐng)求是跨域的時(shí)候, 會(huì)對(duì)發(fā)送的請(qǐng)求進(jìn)行校驗(yàn), 如果校驗(yàn)不通過(guò), 就會(huì)報(bào)跨域錯(cuò)誤. 這個(gè)時(shí)候可能你的請(qǐng)求已經(jīng)發(fā)送成功并且返回了數(shù)據(jù), 但控制臺(tái)報(bào)了一條跨域錯(cuò)誤, 說(shuō)明服務(wù)器后臺(tái)式?jīng)]有任何限制的, ? 是瀏覽器報(bào)的錯(cuò); 說(shuō)白了就是瀏覽器多管閑事, 而不是后臺(tái)不允許
2. 跨域:發(fā)出去的請(qǐng)求不是本域的. ?請(qǐng)求里面 協(xié)議, 域名, 端口任何一個(gè)不一樣, 瀏覽器都會(huì)認(rèn)為是跨域; 比如前臺(tái)是localhost:8080端口, 請(qǐng)求的是localhost:8081端口 , 雖然域名相同, 但端口不一樣, 所以跨域了
3. 發(fā)送的是 XHR(XMLHttpRequest) 請(qǐng)求 (也是最重要的原因); 只要發(fā)送的不是XHR請(qǐng)求, 比如jsonp請(qǐng)求, 就算是跨域, 瀏覽器也不會(huì)報(bào)跨域問(wèn)題
查看全部 -
我想說(shuō)在這里的故事將會(huì)是怎么樣,但是并不是我們所需要的。
查看全部 -
由控制臺(tái)可以看到,Console 報(bào)了一個(gè)錯(cuò)誤,這就是跨域訪問(wèn)安全問(wèn)題
查看全部 -
創(chuàng)建Springboot工程,并編寫后臺(tái)服務(wù)代碼查看全部
-
哈哈哈哈查看全部
-
nginx實(shí)現(xiàn)隱藏跨域: 在下面的a.com.conf文件中配置參數(shù)后,在前端代碼中把請(qǐng)求http://localhost:8081/test地址改成代理地址/ajaxserver
nginx反向代理配置:
支持跨域與隱藏跨域的區(qū)別:
支持跨域:調(diào)用的url地址都是絕對(duì)地址
隱藏跨域:調(diào)用的url都是本域的,是相對(duì)地址,
查看全部 -
String?框架解決方案: @CrossOrigin? 注解,可以在 Controller?上,也可以在?方法上,還可以進(jìn)行細(xì)節(jié)配置。
屬于服務(wù)端改動(dòng)的一種。?
查看全部 -
帶自定義頭的跨域:
1. ajax示例代碼:
2. 請(qǐng)求頭信息
3. 再次請(qǐng)求將會(huì)報(bào)如下錯(cuò)誤信息:
解決辦法:
res.addHeader("Access-Control-Allow-Headers",?"Content-Type,x-header1,x-header2");
這種方式把請(qǐng)求頭寫死了,不推薦
4. 支持所有跨域,示例代碼:
@Override public?void?doFilter(ServletRequest?request,?ServletResponse?response,?FilterChain?chain)?throws?IOException,?ServletException?{ ????HttpServletRequest?req?=?(HttpServletRequest)?request; ????HttpServletResponse?res?=?(HttpServletResponse)?response; ????String?origin?=?req.getHeader("Origin"); ????//res.addHeader("Access-Control-Allow-Origin",?"*");??//允許所有的域跨域 ????//res.addHeader("Access-Control-Allow-Methods",?"*");??//允許所有的方法跨域 ????if(!StringUtils.isEmpty(origin)){ ????????//帶cookie的時(shí)候,origin必須是全匹配,不能使用* ????????res.addHeader("Access-Control-Allow-Origin",?origin);???//允許跨域 ????} ????res.addHeader("Access-Control-Allow-Methods",?"*");??//允許跨域的方法 ????String?headers?=?req.getHeader("Access-Control-Request-Headers"); ????//支持所有自定義頭 ????if(!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); }
查看全部 -
當(dāng)產(chǎn)生跨域的時(shí)候,請(qǐng)求頭中會(huì)多一個(gè)字段,叫做origin,這個(gè)字段有當(dāng)前域的信息。所以在發(fā)送帶cookie的請(qǐng)求,后臺(tái)又不知道調(diào)用方的域的信息時(shí),可以先取到請(qǐng)求頭中origin字段的值再賦值給響應(yīng)頭的access-control-allow-origin字段中。
帶Cookie的跨域: 1. "Access-Control-Allow-Credentials","true" 2. Access-Control-Allow-Origin 不能為* ,必須為【調(diào)用方】的域名+端口 3. 發(fā)送的Cookie是【被調(diào)用方】的cookie
查看全部 -
一、http會(huì)話session依賴于cookie, sessionid存放在cookie中。
二、ajax
1、$.ajax({
????type: "get",
????xhrFields: {
????????widthCredentials: true // 發(fā)送ajax請(qǐng)求的時(shí)候會(huì)帶上cookie
????}
})
2、cookie是加在被調(diào)用方。
服務(wù)端就是被調(diào)用方,而客戶端就是調(diào)用方。在瀏覽器的控制臺(tái)中通過(guò)document.cookie=""? 來(lái)設(shè)置cookie。
3、讀cookie只能讀到本域的。
4、帶cookie時(shí),后臺(tái)代碼注意以下2點(diǎn):
(1)帶cookie的時(shí)候,Access-Control-Allow-Origin,必須是全匹配,如http://localhost:8081, 不能是 *,否則報(bào)錯(cuò),如下:
(2)帶cookie進(jìn)行跨域時(shí),需要設(shè)置以下請(qǐng)求頭:
res.addHeader("Access-Control-Allow-Credentials", "true")
查看全部 -
我們知道非簡(jiǎn)單請(qǐng)求, 每次會(huì)發(fā)出兩次請(qǐng)求, 這會(huì)影響性能. HTTP協(xié)議增加了個(gè)響應(yīng)頭, 可以讓我們?cè)诜?wù)端設(shè)置`Access-Control-Max-Age`來(lái)緩存預(yù)檢請(qǐng)求, 比如說(shuō)我們可以設(shè)置為3600m, 也就是一小時(shí)客戶端只會(huì)在第一次的時(shí)候發(fā)送兩個(gè)請(qǐng)求, 接下來(lái)一個(gè)小時(shí)內(nèi)`OPTIONS`請(qǐng)求就被緩存起來(lái)了.
查看全部 -
問(wèn)題1:瀏覽器是先執(zhí)行請(qǐng)求還是先判斷跨域?
????瀏覽器請(qǐng)求-->判斷響應(yīng)中是否有允許跨域-->發(fā)現(xiàn)不允許跨域,阻止跨域
????說(shuō)明:當(dāng)執(zhí)行跨域請(qǐng)求時(shí),瀏覽器會(huì)提示當(dāng)前接口不被允許,這說(shuō)明瀏覽器已發(fā)出了當(dāng)前請(qǐng)求,但是它的的響應(yīng)內(nèi)容被攔截;如果在Response?header中的Access-Control-Allow-Origin設(shè)置的允許訪問(wèn)源不包含當(dāng)前源,則拒絕數(shù)據(jù)返回給當(dāng)前源。
當(dāng)瀏覽器要發(fā)送跨域請(qǐng)求時(shí),如果請(qǐng)求是復(fù)雜請(qǐng)求,瀏覽器會(huì)先發(fā)送一個(gè)options預(yù)檢命令即一個(gè)options請(qǐng)求,當(dāng)該請(qǐng)求通過(guò)時(shí)才會(huì)再發(fā)送真正的請(qǐng)求。
該option請(qǐng)求會(huì)根據(jù)請(qǐng)求的信息去詢問(wèn)服務(wù)端支不支持該請(qǐng)求。比如發(fā)送的數(shù)據(jù)是json類型(通過(guò)content-type設(shè)置)的話,會(huì)攜帶一個(gè)請(qǐng)求頭Access-Control-Request-Headers: content-type去詢問(wèn)支不支持該數(shù)據(jù)類型,如果支持,則請(qǐng)求就會(huì)通過(guò),并發(fā)送真正的請(qǐng)求
查看全部 -
簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求
1.簡(jiǎn)單請(qǐng)求是先請(qǐng)求,瀏覽器再判斷是否是跨域;而非簡(jiǎn)單請(qǐng)求要先發(fā)送一個(gè)預(yù)檢命令,檢查通過(guò)之后才會(huì)真正的把跨域請(qǐng)求發(fā)出去
2.非簡(jiǎn)單請(qǐng)求常見(jiàn)的是發(fā)送json格式的請(qǐng)求,如圖contentType為“application/json;charset=utf-8”
最后的結(jié)果如下,返回了兩個(gè)請(qǐng)求,一個(gè)是OPTIONS,另一個(gè)是POST請(qǐng)求,其中的OPTIONS就是一個(gè)預(yù)檢命令,成功了之后才會(huì)發(fā)送后面的跨域請(qǐng)求
3.預(yù)檢命令的緩存。因?yàn)檫@種非簡(jiǎn)單請(qǐng)求每次都會(huì)發(fā)送兩次請(qǐng)求,其實(shí)效率是比較低的,但是如果能緩存預(yù)檢命令的話,會(huì)響應(yīng)的提高效率
在服務(wù)器中,添加一個(gè)響應(yīng)頭信息,告訴瀏覽器在截下來(lái)的一個(gè)小時(shí)可以緩存信息,就不需要再發(fā)送預(yù)檢命令
查看全部 -
被調(diào)用方——Filter解決方案:
1. 瀏覽器是先執(zhí)行后判斷
2. 跨域請(qǐng)求和普通請(qǐng)求的區(qū)別:
跨域請(qǐng)求的請(qǐng)求頭中多了一條信息:如下
origin : http://localhost:8081
這個(gè)值是當(dāng)前請(qǐng)求的域名信息,如果 瀏覽器發(fā)現(xiàn)當(dāng)前請(qǐng)求是跨域的時(shí)候,它就會(huì)在當(dāng)前請(qǐng)求頭中添加一個(gè)當(dāng)前域的信息的字段;然后在請(qǐng)求返回的時(shí)候,它會(huì)檢查響應(yīng)頭里面有沒(méi)有允許跨域的信息存在,如果沒(méi)有,它就會(huì)報(bào)錯(cuò)。
查看全部 -
被調(diào)用方解決——支持跨域
查看全部
舉報(bào)