搜尋
首頁php教程PHP开发cros跨域配置

cros跨域配置

Dec 14, 2016 pm 01:14 PM

前端應用為靜態站點且部署在http://web.xxx.com域下,後端應用發布REST API並部署在http://api.xxx.com域下,如何使前端應用程式透過AJAX跨域訪問後端應用呢?這需要使用到CORS技術來實現,這也是目前最好的解決方案了。

[CORS全稱為Cross Origin Resource Sharing(跨域資源共享),服務端只需新增相關回應頭訊息,即可實現客戶端發出AJAX跨域請求。 ]

CORS技術非常簡單,易於實現,目前絕大多數瀏覽器均已支援該技術(IE8瀏覽器也支援了),服務端可透過任何程式語言來實現,只要能將CORS響應頭寫入response對像中即可。

下面我們繼續擴展REST框架,透過CORS技術實現AJAX跨域存取。

首先,我們需要寫一個Filter,用於過濾所有的HTTP請求,並將CORS回應頭寫入response物件中,程式碼如下:

public class CorsFilter implements Filter {  
  
    private String allowOrigin;  
    private String allowMethods;  
    private String allowCredentials;  
    private String allowHeaders;  
    private String exposeHeaders;  
  
    @Override  
    public void init(FilterConfig filterConfig) throws ServletException {  
        allowOrigin = filterConfig.getInitParameter("allowOrigin");  
        allowMethods = filterConfig.getInitParameter("allowMethods");  
        allowCredentials = filterConfig.getInitParameter("allowCredentials");  
        allowHeaders = filterConfig.getInitParameter("allowHeaders");  
        exposeHeaders = filterConfig.getInitParameter("exposeHeaders");  
    }  
  
    @Override  
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
        HttpServletRequest request = (HttpServletRequest) req;  
        HttpServletResponse response = (HttpServletResponse) res;  
        if (StringUtil.isNotEmpty(allowOrigin)) {  
            List<String> allowOriginList = Arrays.asList(allowOrigin.split(","));  
            if (CollectionUtil.isNotEmpty(allowOriginList)) {  
                String currentOrigin = request.getHeader("Origin");  
                if (allowOriginList.contains(currentOrigin)) {  
                    response.setHeader("Access-Control-Allow-Origin", currentOrigin);  
                }  
            }  
        }  
        if (StringUtil.isNotEmpty(allowMethods)) {  
            response.setHeader("Access-Control-Allow-Methods", allowMethods);  
        }  
        if (StringUtil.isNotEmpty(allowCredentials)) {  
            response.setHeader("Access-Control-Allow-Credentials", allowCredentials);  
        }  
        if (StringUtil.isNotEmpty(allowHeaders)) {  
            response.setHeader("Access-Control-Allow-Headers", allowHeaders);  
        }  
        if (StringUtil.isNotEmpty(exposeHeaders)) {  
            response.setHeader("Access-Control-Expose-Headers", exposeHeaders);  
        }  
        chain.doFilter(req, res);  
    }  
  
    @Override  
    public void destroy() {  
    }  
}

以上CorsFilter將從web.xml中讀取相關Filter初始化參數,並將在處理HTTP請求時將這些參數寫入對應的CORS回應頭中,下面大致描述一下這些CORS回應頭的意義:


Access-Control-Allow-Origin:允許存取的客戶端域名,例如:http://web.xxx.com,若為*,則表示從任意網域都能訪問,即不做任何限制。

Access-Control-Allow-Methods:允許存取的方法名,多個方法名稱以逗號分割,例如:GET,POST,PUT,DELETE,OPTIONS。

Access-Control-Allow-Credentials:是否允許請求帶有驗證訊息,若要取得客戶端網域下的cookie時,需要將其設為true。

Access-Control-Allow-Headers:允許服務端存取的用戶端請求頭,多個請求頭用逗號分割,例如:Content-Type。

Access-Control-Expose-Headers:允許客戶端存取的服務端回應頭,多個回應頭用逗號分割。

需要注意的是,CORS規格中定義Access-Control-Allow-Origin只允許兩種取值,要麼為*,要麼為具體的域名,也就是說,不支援同時配置多個域名。為了解決跨多個域的問題,需要在程式碼中做一些處理,這裡將Filter初始化參數作為一個網域的集合(用逗號分隔),只需從目前請求中取得Origin請求頭,就知道從哪個網域中發出的請求,若該請求在以上允許的網域集合中,則將其放入Access-Control-Allow-Origin回應頭,這樣跨多個網域的問題就輕鬆解決了。

以下是web.xml中配置CorsFilter的方法:

<filter>  
    <filter-name>corsFilter</filter-name>  
    <filter-class>com.xxx.api.cors.CorsFilter</filter-class>  
    <init-param>  
        <param-name>allowOrigin</param-name>  
        <param-value>http://web.xxx.com</param-value>  
    </init-param>  
    <init-param>  
        <param-name>allowMethods</param-name>  
        <param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>  
    </init-param>  
    <init-param>  
        <param-name>allowCredentials</param-name>  
        <param-value>true</param-value>  
    </init-param>  
    <init-param>  
        <param-name>allowHeaders</param-name>  
        <param-value>Content-Type</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>corsFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>

完成以上過程即可實現AJAX跨域功能了,但似乎還有另一個問題,由於REST是無狀態的,後端應用發布的REST API可在使用者未登入的情況下被任意調用,這顯然是不安全的,如何解決這個問題?我們需要為REST請求提供安全機制。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。