瀏覽器使用的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.
不過,最後提醒一句:以上方式只是在開發測試的時候,爲了方便才這麼作的,安全緣由,生產環境強烈不推薦。
謝謝你們~