我正在尝试使用Spring的RestTemplate进行跨源请求.通信是在两个Spring-boot webapps之间完成的,这两个webapp都运行在localhost但不同的端口上.我所做的是:
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setOrigin("http://localhost:8083");
httpHeaders.add("Authorization", token);
HttpEntity httpEntity = new HttpEntity<>(httpHeaders);
ParameterizedTypeReference> beanType = new ParameterizedTypeReference>() {};
ResponseEntity> list = restTemplate.exchange(serviceURL, HttpMethod.GET, httpEntity, beanType);
执行调用,"授权"标题传递得很好,但无论我尝试什么,接收端都没有"Origin"标题.当我使用其他工具(SoapUI,RestClient Chrome插件等)创建一个simillar请求时,标题就像我提供的那样传递.
要在接收端打印所有标头,我正在使用javax.servlet.Filter的实现:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
log.info(headerName + ": " + request.getHeader(headerName));
}
}
使用RestTemplate时为什么不传递origin头?
有同样的问题,我花了一个世纪来修复.
根本原因是来自RestTemplate文档的这一行
注意:默认情况下,RestTemplate依赖于标准JDK工具来建立HTTP连接.
如果您HttpUrlConnection
在Java中检查类的源代码,您将在下面的代码块中找到,并且header Origin
是禁止更改的受限标头之一:
/* * Restrict setting of request headers through the public api * consistent with JavaScript XMLHttpRequest2 with a few * exceptions. Disallowed headers are silently ignored for * backwards compatibility reasons rather than throwing a * SecurityException. For example, some applets set the * Host header since old JREs did not implement HTTP 1.1. * Additionally, any header starting with Sec- is * disallowed. * * The following headers are allowed for historical reasons: * * Accept-Charset, Accept-Encoding, Cookie, Cookie2, Date, * Referer, TE, User-Agent, headers beginning with Proxy-. * * The following headers are allowed in a limited form: * * Connection: close * * See http://www.w3.org/TR/XMLHttpRequest2. */ private static final boolean allowRestrictedHeaders; private static final SetrestrictedHeaderSet; private static final String[] restrictedHeaders = { /* Restricted by XMLHttpRequest2 */ //"Accept-Charset", //"Accept-Encoding", "Access-Control-Request-Headers", "Access-Control-Request-Method", "Connection", /* close is allowed */ "Content-Length", //"Cookie", //"Cookie2", "Content-Transfer-Encoding", //"Date", //"Expect", "Host", "Keep-Alive", "Origin", // "Referer", // "TE", "Trailer", "Transfer-Encoding", "Upgrade", //"User-Agent", "Via" };
只需设置JVM参数,就可以轻松解决此问题
-Dsun.net.http.allowRestrictedHeaders=true
或在代码中添加一行
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
这抑制了限制.