问题背景:
前后端开发完之后打包部署到服务器上,进行测试的时候,发现有个接口总是报“请求头缺少参数SESSION_ID”,碰到这个问题,作为一个后端开发,肯定会说前端没传呗!前端同事信誓旦旦的说的确传了,但是本地IDE启动项目进行联调的时候,后端确实收到了请求头中的参数,然后意识到可能是服务器环境问题,请求有没有跨域?有没有被转发?如果有的话,这之间会不会把请求头中的参数丢失? 然后一个一个排查,前后端分离,必然涉及到跨域,但是已经做了跨域处理,保证了请求头中的参数不会丢失;然后用命令看了下服务器上有没有nginx,发现有nginx,然后去查了一下,nginx代理转发丢失请求头的相关问题,发现nginx果然会丢失带下划线的请求头(如果不配置的话),然后去nginx的配置文件,配置相关配置,重启服务。
解决:
后端跨域配置:
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class SimpleCORSFilter extends OncePerRequestFilter {
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
String origin = request.getHeader("Origin");
response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "access_token");
response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
"Origin, X-Requested-With, Content-Type, ACTION, SESSION_ID, SOURCE, T_SOURCE, sessionId");
// XX请求
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,
"GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE");
response.setHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "86400");
return;
}
filterChain.doFilter(request, response);
}
}
nginx相关配置: nginx.conf 在配置http部分 添加如下配置,如图
underscores_in_headers on; ##(默认值是off)
最后,建议请求头中不要使用带下划线的参数!!!