剛開始在使用jqueryajax跨域請求zuul網關時,在后台發現一直拿不到前台請求的json數據,而前台也一直拿不到后台的響應數據。打開瀏覽器調試程序發現,本身ajax的POST請求統一都變成了option,這是怎么回事呢?
根本原因就是,W3C規范這樣要求了!在跨域請求中,分為簡單請求(get和部分post,post時content-type屬於application/x-www-form-urlencoded,multipart/form-data,text/plain中的一種)和復雜請求。而復雜請求發出之前,就會出現一次options請求。
什么是options請求呢?它是一種探測性的請求,通過這個方法,客戶端可以在采取具體資源請求之前,決定對該資源采取何種必要措施,或者了解服務器的性能。
在ajax中出現options請求,也是一種提前探測的情況,ajax跨域請求時,如果請求的是json,就屬於復雜請求,因此需要提前發出一次options請求,用以檢查請求是否是可靠安全的,如果options獲得的回應是拒絕性質的,比如404\403\500等http狀態,就會停止post、put等請求的發出。
根據這個就好解釋多了,那么在這里我更改一下zuul的代碼讓其支持,在這里定義一個filter,部分代碼如下:
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
String requestBody = null;
try {
requestBody = StreamUtils.copyToString(requestContext.getRequest().getInputStream(), Charsets.UTF_8);
} catch (IOException e) {
log.error("", e);
}
requestContext.addOriginResponseHeader("content-type", "application/json;charset=utf-8");
//設置可以跨域訪問
requestContext.addZuulResponseHeader("Access-Control-Allow-Headers", "content-type,x-requested-with");
requestContext.addZuulResponseHeader("Access-Control-Allow-Origin", "*");
requestContext.addZuulResponseHeader("content-type", "application/json;charset=utf-8");
// 如果為options請求則一定要返回200狀態碼
if ("options".equals(requestContext.getRequest().getMethod().toLowerCase())) {
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(HttpStatus.OK.value());
return null;
}
//....省略部分代碼
}
