用springmvc 開發爲 app 提供後臺服務遇到跨域請求的問題

瀏覽器使用的chrome,安裝了cors插件(開啓容許跨域請求)web

而後訪問遠程服務器提供的服務的時候,瀏覽器console 輸出以下形式的錯誤信息:ajax

問題1.OPTION: xxxxxx url地址spring

問題2.XMLHttpRequest cannot load :xxxxx url 地址chrome

Request header field xxxx is not allowed by Access-Control-Allow-Headers跨域

----------瀏覽器

OPTIONS方法是用於請求得到由Request-URI標識的資源在請求/響應的通訊過程當中可使用的功能選項。安全

經過這個方法,客戶端能夠在採起具體資源請求以前,決定對該資源採起何種必要措施,或者瞭解服務器的性能。服務器

若是想詳細瞭解ajax跨域請求,能夠參考這位做者的三篇文章,It's awesome!cookie

詳解AJAX跨域請求:app

http://blog.csdn.net/net_lover/article/details/5172509

http://blog.csdn.net/net_lover/article/details/5172522 

http://blog.csdn.net/net_lover/article/details/5172532

---------------

瀏覽器在發送真正的http請求以前會發送OPTION類型的請求,執行預檢,檢查服務器支持的請求類型,

對請求頭容許的特殊說明,獲得服務器的批准,容許才發送實際的請求,服務器也能夠向瀏覽器發送通知,

知會瀏覽器是否須要在請求中向服務器傳遞某些認證信息(cookie,或者Authentication認證數據),

下面的圖形象描述了這個過程:

 

 來自維基百科:https://en.wikipedia.org/wiki/Cross-origin_resource_sharing

別的很少說,就是說咱們須要在服務器端容許,OPTION 類型的請求,能夠解決問題1;

在服務器端設置容許的 源、請求頭包含信息、容許的方法,deviceName,deviceID  是個人項目須要的,根據您的須要去設置,

'Access-Control-Allow-Origin': '*',

'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept,deviceName,deviceID',

'Access-Control-Allow-Methods': 'GET, POST, PUT',

---------------

spring中的設置方法:

web.xml中作以下配置:

<security-constraint>    
   <web-resource-collection>    
      <url-pattern>/*</url-pattern>    
      <http-method>PUT</http-method>    
      <http-method>DELETE</http-method>    
      <http-method>HEAD</http-method>    
      <!--<http-method>OPTIONS</http-method>-->  <!-- 注意須要去掉的就是這行,解決問題1 -->  
      <http-method>TRACE</http-method>    
   </web-resource-collection>    
   <auth-constraint>    
   </auth-constraint>    
</security-constraint>    
<login-config>    
    <auth-method>BASIC</auth-method>    
</login-config> 
  <!-- rest cors request filter 解決問題2-->
    <filter>
        <display-name>RequestHeaderFilter</display-name>
        <filter-name>RequestHeaderFilter</filter-name>
        <filter-class>com.xxx.filter.RequestHeaderFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RequestHeaderFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

新增一個RequestHeaderFilter:

public final class RequestHeaderFilter implements Filter {

    /**
     * Default constructor.
     */
    public RequestHeaderFilter() {
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        // 設置容許跨域訪問
        HttpServletResponse httpServletResponse = (HttpServletResponse)response;
        
        httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
        // 容許 header中包括 deviceName,deviceID
        httpServletResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,deviceName,deviceID");
        
        chain.doFilter(request, httpServletResponse);
    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
    }

}

 

至此,配置修改完畢,it works great.

不過,最後提醒一句:以上方式只是在開發測試的時候,爲了方便才這麼作的,安全緣由,生產環境強烈不推薦。

謝謝你們~

相關文章
相關標籤/搜索