『壹』 如何解決前端跨域問題
可以使用伺服器代理或者在後端設置允許跨域。
現在的項目一般是在後端設置允許跨域,前端在帶有允許跨域的情況下,可以像沒有跨域一樣正常訪問。
如果前端單獨發布到伺服器,也可以在伺服器是設置代理,使用代理轉發請求。
『貳』 後端解決前端跨域請求問題
場景:前後端分離,頁面和後端項目部署在不同伺服器,出現請求跨域問題。
原因:CORS:跨來源資源共享(CORS)是一份瀏覽器技術的規范,提供了 Web 服務從不同網域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,是 JSONP 模式的現代版。與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以讓網頁設計師用一般的 XMLHttpRequest,這種方式的錯誤處理比JSONP要來的好,JSONP對於 RESTful 的 API 來說,發送 POST/PUT/DELET 請求將成為問題,不利於介面的統一。但另一方面,JSONP 可以在不支持 CORS 的老舊瀏覽器上運作。不過現代的瀏覽器(IE10以上)基本都支持 CORS。
預檢請求(option):在 CORS 中,可以使用 OPTIONS 方法發起一個預檢請求(一般都是瀏覽檢測到請求跨域時,會自動發起),以檢測實際請求是否可以被伺服器所接受。預檢請求報文中的 Access-Control-Request-Method 首部欄位告知伺服器實際請求所使用的 HTTP 方法;Access-Control-Request-Headers 首部欄位告知伺服器實際請求所攜帶的自定義首部欄位。伺服器基於從預檢請求獲得的信息來判斷,是否接受接下來的實際請求。
解決方案:
1、創建一個過濾器,過濾options請求。
package com.biz.eisp.sci.util;
import org.apache.commons.httpclient.HttpStatus;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 解決跨域問題
*
*/
public class CorsFilterimplements Filter {//filter 介面的自定義實現
public void init(FilterConfig filterConfig)throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
response.setHeader("Access-Control-Allow-Origin", "*");
if ("OPTIONS".equals(request.getMethod())){//這里通過判斷請求的方法,判斷此次是否是預檢請求,如果是,立即返回一個204狀態嗎,標示,允許跨域;預檢後,正式請求,這個方法參數就是我們設置的post了
response.setStatus(HttpStatus.SC_NO_CONTENT); //HttpStatus.SC_NO_CONTENT = 204
response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS, DELETE");//當判定為預檢請求後,設定允許請求的方法
response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with"); //當判定為預檢請求後,設定允許請求的頭部類型
response.addHeader("Access-Control-Max-Age", "1"); // 預檢有效保持時間
}
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
2、修改web.xml文件
<filter>
<filter-name>cors</filter-name>
<filter-class>com.biz.eisp.sci.util.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/* </url-pattern>
</filter-mapping>
3、spring-mvc.xml添加HttpRequestHandlerAdapter http請求處理器適配器。
HttpRequestHandlerAdapter作為HTTP請求處理器適配器僅僅支持對HTTP請求處理器的適配。它簡單的將HTTP請求對象和響應對象傳遞給HTTP請求處理器的實現,它並不需要返回值。它主要應用在基於HTTP的遠程調用的實現上。
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
『叄』 前端的跨域問題理解
前端真的的是亂的一筆。--來自iOS開發者的一聲哀鳴
需要把前端看成兩部分,一部分是頁面,另一部分是介面(或者加數據資源)。前端頁面中調介面是有限制的,同源策略(SOP)要求我們調用的介面必須和頁面在同一域名下,說是為了保證數據的安全。所謂同源:協議+域名+埠
但實際情況是,在前後端分離的大趨勢下,好多頁面和介面的伺服器分布在不同的域名下。比如在開發時,前端頁面分為本地環境、測試環境、模擬環境、正式環境,而介面也分為測試環境、模擬環境、正式環境,當然也可以有本地環境。他們在不同的域名下或IP下或者埠下,是不同源的。或者平時我們也能遇到需要調用不同的伺服器數據資源。顯然,同源策略保障了部分安全的同時,給開發造成了很多的麻煩。
所以,跨域問題是每個前端繞不過去的坎兒。
解決辦法有兩個方向,一個是前端解決,一個是服務端介面解除限制。
前端解決就是通過jsonp、jquery ajax、axios配置代理等。還有個簡單的,比如Mac用戶,可以使用Charles工具設置代理,臨時使用。
服務端解決可以通過nginx反向代理設置允許跨域請求的域名、或者設置Access-Control-Allow-Origin,允許跨域資源共享等。
具體解決方案可參考 https://segmentfault.com/a/1190000011145364
反觀iOS,輪廓簡直不要太清晰,大部分時候只用專注於開發,沒有各種亂七八糟的事情。
『肆』 Nginx部署前後端項目時的跨域問題
最近在准備一個小項目來著,使用tomcat部署後端的SpringBoot項目,然後使用Nginx部署前端界面並轉發後端請求到相應的tomcat集群時,發生了跨域問題,解決過程欲仙欲死,特在此記錄一下。
Nginx跨域配置方法一
嚴格說來,這種方式並不算是跨域請求,因為這種配置要求後端請求的url必須為 http://shop.mk-shop.com/mk-shop-api/xxxx 的形式,也就是說前端項目的請求地址必須進行更改為和客戶端頁面訪問時的url地址一樣,這樣貌似也就沒有跨域問題了。如果前端項目不同模塊的請求地址不一樣,則都需要進行更改。
Nginx跨域配置方法二
注意: api.mk-shop.com 是後端api的請求前綴,也就是客戶端非同步載入時的請求地址,以我的項目的後端請求地址為例:
SpringBoot後端處理跨域時可以配置過濾器來實現
注意: 使用過程中,新版本的springboot可能會報錯不允許在setAllowedOrigins包含 * ,此時需要使用setAllowedOriginPatterns代替。
『伍』 請求介面時跨域問題,前端解決方法
在前後端介面請求中,由於瀏覽器的限制,會出現跨域的情況。常用的跨域方案有:
1、JSONP跨域
2、Nginx反向代理
3、伺服器端修改header
4、document.domain
5、window.name
6、postMessage
7、後台配置運行跨域
當一個請求url的 協議、域名、埠 三者之間任意一個與當前頁面url不同即為跨域
特別注意兩點:
1、如果是協議和埠造成的跨域問題「前台」是無能為力的,
2、在跨域問題上,域僅僅是通過「URL的首部」來識別而不會去嘗試判斷相同的ip地址對應著兩個域或兩個域是否在同一個ip上。
『陸』 web前端跨域的一些解決方案
沒有歸納之前對跨域的一些說法是模糊的,什麼jsonp啊,跨域原理啊,心裡只有一個大概的說法,知道這個東西,然後用的時候直接網路Ctrl+C,後來閑下來決定整理一波這些知識點,需知其所以然。
那麼,其實這是瀏覽器對我們的一種保護機制,把壞人擋在門外。那麼,問題來了,我們怎麼確定門外的人到底是好人還是壞人呢?瀏覽器關上了壞人的一扇門,留給了我們好人一扇窗。
JSONP跟JSON沒有關系..就好像JavaScript和Java一樣
瀏覽器對script、img(這些標簽的請求方式都是 GET ,所以jsonp不支持 POST )這種標簽沒有限制,我們就可以這樣干
因此,實現CORS通信的關鍵是伺服器。只要伺服器實現了CORS介面,就可以跨源通信。
伺服器端對於CORS的支持,主要就是通過設置 Access-Control-Allow-Origin 來進行的。如果瀏覽器檢測到相應的設置,就可以允許Ajax進行跨域的訪問。 更多有關跨域資源共享 CORS 的知識
瀏覽器中可以查看對應的響應頭,舉個例子,如下
服務端允許CORS,服務端需要針對介面設置的一系列響應頭 (Response Headers)
1.簡單請求
目前大多數情況都採用這種方式。簡單請求只需要設置 Access-Control-Allow-Origin 即可。滿足以下兩個條件,就屬於簡單請求。
2.非簡單請求
非簡單請求會發出一次預檢測請求,返回碼是204,預檢測通過才會真正發出請求,這才返回200。來看栗子:
非簡單請求需要根據不同情況配置不同的響應頭,一系列響應頭配置項見上方
這個說法相信不陌生,我們依然使用前端域名請求,然後有一個 中介商---代理 把這個請求轉發到真正的後端域名上,那也就不存在跨域問題了。
比較普遍的Nginx,簡單的配置一下就可以了。了解更多的配置信息: nginx詳解
然後前端這邊的請求地址是 http://localhost:9099/api/xxx ,然後Nginx監聽到地址是 localhost:9099/api 的請求,就幫我們轉發到真正的服務端地址 http://.com
CORS與JSONP的使用目的相同,但是比JSONP更強大。JSONP只支持GET請求,CORS支持所有類型的HTTP請求。JSONP的優勢在於支持老式瀏覽器,以及在服務端同意jsonp方式時,可以向不支持CORS的網站請求數據。Nginx可以說是最方便的,不過需要部署Nginx才行,需要對伺服器有一定的理解,不太適合剛入門的同學,當然也可以請後台同學幫忙部署。
window.postMessage(data,origin) 是 HTML5 的一個介面,專注實現不同窗口不同頁面的跨域通訊。
現在是這么一個情況,由於同源策略的限制下, a.html 不能操作iframe( b.html )裡面的dom,那麼使用postMessage就可以解決這一情況
然後 b.html 頁面通過message事件監聽並接受消息:
這種方式只適合主域名相同,但子域名不同的iframe跨域。
比如主域名是 http://.com/:8888 ,子域名是 http://child..com/:8888 ,這種情況下給兩個頁面設置相同的document.domain即document.domain = .com 就可以訪問各自的window對象了。
前端跨域整理
不要再問我跨域的問題了
『柒』 解決前後端分離開發,後端重定向不到前端頁面問題
公司項目使用的是springboot+angularjs這種前後端不完全分離的開發方式,前段時間把項目改成springboot+vue前後端完全分離,開發過程中有個後端重定向問題。後端項目地址: http://localhost:8080/ ,前端項目地址: http://localhost:9090/ ,比如後端 redirct:"/#/main" 重定向到這個頁面,瀏覽器重定向的卻是 http://localhost:8080/#/main 後端項目的地址,找了很久最終在webpack中找到解決方案。
我們可以在 devServer.proxy.onProxyRes 中做處理,配置如下:
『捌』 後端使用springboot+tio-http-server,前端使用element-ui+websocket,如何解決跨域問題後端已支持跨域
最便捷的還是使用nginx反向代理吧。
例如,假設後端的ip和埠號為:192.168.111.222:8080,前端的ip和埠號為:192.168.111.222:8001,此時前後端埠不一致導致跨域。
部署一個ngnix,修改ngnix安裝目錄下的/config/nginx.conf文件,剛安裝的ngnix的配置文件里默認應該為:
配置好ngnix後,你前端工程里訪問後端介面時,只需要將請求url修改為http://192.168.111.222:8001/api/即可。
例如你原來的登錄後端介面可能是訪問http://192.168.111.222:8080/login,你要修改為訪問http://192.168.111.222:8001/api/login