Principle: When a cross-domain request occurs, it is divided into two requests. The first request is called a sniffing request, and the prefight request is the http OPTIONS request. After the success, the real request is made. These two requests are written in code. Browse The server does not make an options request.
The tomcat server needs to return the request header and process the options request:
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
if (encoding == null) {
encoding = config.getInitParameter("encoding");
}
servletRequest.setCharacterEncoding(encoding);
servletResponse.setCharacterEncoding(encoding);
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
/**cors modified start**/
StringBuilder headers = new StringBuilder();
Enumeration<String> headerNames = request.getHeaders("Access-Control-Request-Headers");
if(Objects.nonNull(headerNames)) {
while (headerNames.hasMoreElements()) {
headers.append(headerNames.nextElement()).append(",");
}
}
response.setHeader("Access-Control-Allow-Headers", headers.toString());
/**cors modified end**/
if ("options".equalsIgnoreCase(request.getMethod())) {
response.setStatus(204);
} else {
chain.doFilter(request, response);
}
log.warn("url=" + ((HttpServletRequest)request).getRequestURL()+",method="+((HttpServletRequest)request).getMethod());
}
Nginx server request processing:
server {
listen 9000 ssl;
listen [::]:9000 ssl;
root /usr/share/nginx/html;
ssl_certificate s1cert.pem;
ssl_certificate_key s1cert.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
add_header X-Frame-Options "ALLOW-FROM http://stand.alone.version/";
add_header Access-Control-Max-Age 3600;
# add_header X-Content-Type-Options nosniff;
location / {
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://172.19.0.2:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Prefight request principle:
For example, a client might DELETE
initiate a preflight request to the server to ask the server if it can accept a DELETE request before actually sending a request:
OPTIONS /resource/foo Access-Control-Request-Method: DELETE Access-Control-Request-Headers: origin, x-requested-with Origin: https://foo.bar.org
If the server allows it, the server responds to the preflight request. And its response header Access-Control-Allow-Methods will DELETE
be included in it:
HTTP/1.1 200 OK Content-Length: 0 Connection: keep-alive Access-Control-Allow-Origin: https://foo.bar.org Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE Access-Control-Max-Age: 86400
Reference instructions: