Article directory
- foreword
- Two commonly used methods for cross-domain processing
-
- 1. How does springboot deal with cross-domain issues?
- 2. How does nginx handle cross-domain issues?
-
- 2.1 Configure the response header parameters for the Nginx server
- 2.2. Detailed interpretation of each parameter
- Nginx configuration domain name spans multiple domain names
- 2.3, nginx handles various error reports encountered in the cross-domain process
- 2.4, preflight request (preflight request) error
-
- 2.4.1. Expected request process (send options request/response first, then send post request)
- 2.4.2, pre-check request error
- 2.4.3. How to solve the error report of the pre-check request?
- 2.4.4 Access-Control-Allow-Origin can only be set once, after configuration in the backend, it cannot be configured again in nginx
- 2.5. The request header carries additional information such as Authorization
- 2.6. In-depth analysis and resolution of cross-domain errors in the new version of Google: request client is not a secure context and the resource is in more-private address
- How to configure https (configure ssl in nginx)
- Summarize
foreword
提示:本人在生产部署服务时遇到一系列跨域问题和https配置问题,特此做以下记录:
Preface 1. What is cross-domain?
Cross-domain means that page a wants to obtain resources of page b. If the protocols, domain names, ports, and subdomain names of pages a and b are different, or page a is an ip address and page b is a domain name address, all access actions are cross-domain. domain, and browsers generally restrict cross-domain access for security reasons, that is, cross-domain resource requests are not allowed.
Preface 2. What are the conditions for cross-domain generation?
注意:跨域限制访问,其实是浏览器的限制。理解这一点很重要。所以,当用java(或者其他语言)调用RESTful api,从来不会报什么跨域错误
Two commonly used methods for cross-domain processing
1. How does springboot deal with cross-domain issues?
1.1 Separate configuration in controller
Add @CrossOrigin cross-domain annotations to each Controller class
1.2 Global configuration in the @configation class
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 匹配了所有的URL
.allowedHeaders("*") // 允许跨域请求包含任意的头信息
.allowedMethods("*") // 设置允许的方法
.allowedOrigins("*") // 设置允许跨域请求的域名
.allowCredentials(true); // 是否允许证书,默认false
}
}
1.3 Add a response header to the filter
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
res.addHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));
res.addHeader("Access-Control-Allow-Methods", "*");
res.addHeader("Access-Control-Allow-Headers", "Accept,Authorization,DNT,Content-Type,Referer,User-Agent");
res.addHeader("Access-Control-Allow-Credentials","true"); // 允许携带验证信息
chain.doFilter(req, res);
}
2. How does nginx handle cross-domain issues?
2.1 Configure the response header parameters for the Nginx server
When a 403 cross-domain error occurs and the No 'Access-Control-Allow-Origin' header is present on the requested resource, you need to configure the response header parameters for the Nginx server.
location / {
add_header Access-Control-Allow-Origin *; //允许所有请求访问
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; //允许访问的请求类型
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
//预检请求需要用到
if ($request_method = 'OPTIONS') {
return 204;
}
}
2.2. Detailed interpretation of each parameter
- Access-Control-Allow-Origin
服务器默认是不被允许跨域的,给Nginx服务器配置`Access-Control-Allow-Origin *`后,表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。
- Access-Control-Allow-Headers is to prevent the following errors:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
This error indicates that the value of the current request Content-Type is not supported. In fact, it was caused by us initiating a type request of "application/json". A concept is involved here: preflight request (preflight request), please see the introduction of "preflight request" below.
-
Access-Control-Allow-Methods is to prevent the following error:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response. -
Adding a 204 return to OPTIONS is to deal with the error that Nginx still refuses access when sending a POST request
发送"预检请求"时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
Nginx configuration domain name spans multiple domain names
Method 1: Use nginx built-in variables (commonly used)
server {
set $cors '';
if ($http_origin ~* "^http://deomain01:port$") {
set $cors $http_origin;
}
if ($http_origin ~* "^http://deomain02:port$") {
set $cors $http_origin;
}
if ($http_origin ~* "^http://deomain002:port$") {
set $cors $http_origin;
}
location /live{
...
add_header 'Access-Control-Allow-Origin' '$cors';
add_header 'Access-Control-Allow-Credentials' 'true';
# 为预检请求加的header
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE';
#为预检请求加的header
add_header 'Access-Control-Allow-Headers' '*';
}
Explanation: The format of $http_origin is for nginx to take the value of XXX in the header of the request.
The origin is taken here, and the general cross-domain request will put the source of the request in origin (the browser will add the header of origin to the header of the cross-domain request) $ cors
variable gets the desired cross-domain domain name and assigns it to " add_header 'Access-Control-Allow-Origin' '$cors'".
Method 2: use map
map $http_origin $cors_list{
default http://aaa.cn;
"~ http://bbb.cn" http://bbb.cn;
}
server {
listen 8089;
server_name localhost;
location /live{
...
add_header 'Access-Control-Allow-Origin' '$cors_list';
add_header 'Access-Control-Allow-Credentials' 'true';
# 为预检请求加的header
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE';
#为预检请求加的header
add_header 'Access-Control-Allow-Headers' '*';
}
Explanation:
The map command is provided by the ngx_http_map_module module, which is loaded by nginx by default.
语法: map $var1 $var2 {
…}
默认值: -
配置段: http
map为一个变量设置的映射表。映射表由两列组成,匹配模式和对应的值。
在map块里的参数指定了源变量值和结果值的对应关系。
default: 没有匹配结果将使用的默认值。如果没有设置default,将会用一个空的字符串作为默认的结果。
匹配模式可以是一个简单的字符串或者正则表达式,使用正则表达式要用(‘~’)。
Method 3: Regular matching of third-level domain names
location / {
if ($http_origin ~* (http?://.*\.aliuncle\.top$)) {
add_header Access-Control-Allow-Origin $http_origin;
}
index index.php;
try_files $uri $uri/ /index.php?$args;
}
Note: When configuring cross-domain in the nginx.conf configuration file, remember to clear the client such as the browser cache, otherwise the configuration will not take effect.
2.3, nginx handles various error reports encountered in the cross-domain process
1. The cross-domain request cannot carry the identity credential cookie error ()
Description of the problem: The identity credential cookie cannot be passed in the request anyway
Solution:
front-end:
1. Set the attribute withCredentials of the request object to true when the front-end requests;
2. The backend supports the response header Credentials as true
注意:除了 Access-Control-Allow-Credentials 之外,跨域发送 Cookie 还要求 Access-Control-Allow-Origin 不允许使用通配符。 事实上不仅不允许通配符,而且 只能指定单一域名:
, otherwise a cros error will be reported
2.4, preflight request (preflight request) error
Introduction:
The Cross-Origin Resource Sharing (CORS) standard adds a new set of HTTP header fields, allowing the server to declare which origin sites have permission to access which resources. In addition, the specification requires that for those HTTP request methods that may have side effects on server data (especially HTTP requests other than GET, or POST requests with certain MIME types ), the browser must first use the OPTIONS method to initiate a preflight request ( preflight request), so as to know whether the server allows the cross-domain request. After the server confirms the permission, the actual HTTP request is initiated. In the return of the preflight request, the server can also notify the client whether to carry identity credentials (including Cookies and HTTP authentication related data).
In fact, the request whose Content-Type field is application/json is the above-mentioned POST request with certain MIME types. CORS stipulates that Content-Types that do not belong to the following MIME types are all pre-check requests:
application/x-www-form-urlencoded
multipart/form-data
text/plain
2.4.1. Expected request process (send options request/response first, then send post request)
2.4.2, pre-check request error
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
Explanation:
The application/json request will add a "pre-check" request before the formal communication. This "pre-check" request will bring header information. When the server responds, if the returned header information does not contain Access-Control -Allow-Headers: Content-Type indicates that non-default Content-Type is not accepted. That is, the above error occurs:
预检请求头信息
Access-Control-Request-Headers: Content-Type:
OPTIONS /api/test HTTP/1.1
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
2.4.3. How to solve the error report of the pre-check request?
The preflight request was also mentioned earlier, we only need to add our judgment before the nginx proxy to make nginx return a processing success status code when it encounters an options request
//预检请求需要用到
if ($request_method = 'OPTIONS') {
return 204;
}
Detailed explanation of nginx status code
2.4.4 Access-Control-Allow-Origin can only be set once, after configuration in the backend, it cannot be configured again in nginx
The following error is reported:
Explanation: The Access-Control-Allow-Origin value returned by the server should not be a list, because the browser will only accept one value, and it cannot be empty.
2.5. The request header carries additional information such as Authorization
报错:(Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight)
2.5.1, Explanation
The response header Access-Control-Allow-Headers is used in the preflight request (preflight request), and lists the header information that will appear in the Access-Control-Request-Headers field of the formal request. Simple headers, such as simple headers, Accept, Accept-Language, Content-Language, Content-Type (limited to the three MIME values of application/x-www-form-urlencoded, multipart/form-data or text/plain after parsing type (excluding parameters)), they are always supported and do not need to be specifically listed in this header.
Additional request header information such as Authorization and x-token needs to be allowed. This error is reported through request preprocessing to know that the request header Authorization is not allowed, so it reports a cross-domain
2.5.2. Solve
It is necessary to add the allowed header Authorization, and when it is judged that the request method is options, return ok (200) to the client, so that the formal post request can continue.
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, DELETE, PUT, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, X-Custom-Header, Access-Control-Expose-Headers, Token, Authorization';
add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Max-Age' 1728000;
2.6. In-depth analysis and resolution of cross-domain errors in the new version of Google: request client is not a secure context and the resource is in more-private address
2.6.1 Reasons for error reporting
Error: An insecure requester requested a more private local resource
Reason: Starting from version 94 of Google, Google has updated the private network for unsafe websites to block such requests to access more private resources. At the same time, before requesting private network resources, an OPTIONS preflight request will be sent first.
2.6.2 Solutions
1. Replace non-Google kernel browsers (using Firefox, edge, etc.) or lower the version
2. Modify the settings of Google Chrome Solution
: Disable the settings. For Google Chrome versions between 94 and 101, you can modify the browser settings so that requests for private resources sent by http websites can be successfully sent.
Proceed as follows:
Step 1: Enter in the browser: chrome://flags/#block-insecure-private-network-requests
Step 2: Change the Default of the Block insecure private network requests. item to Disabled, and restart the browser (different versions have different configurations, please refer to the following reference link for details). Refer to link 3. Modify the access method of intranet pictures and other resources
,
all Using https access can fundamentally solve the problem
How to configure https (configure ssl in nginx)
1. Configuration
Summarize the following steps: apply for ssl->ssl file storage to the server->nginx configure ssl
server {
listen 8002 ssl;
server_name temp.3zyun.com ; #公网ip 115.148.208.122
client_max_body_size 1024M;
ssl_certificate /usr/local/nginx/yjssl/7604469_temp.3zyun.com_nginx/7604469_temp.3zyun.com.pem;
ssl_certificate_key /usr/local/nginx/yjssl/7604469_temp.3zyun.com_nginx/7604469_temp.3zyun.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on ;
location / {
proxy_pass http://bpm-server/;
proxy_set_header Host $host:$server_port;
}
}
注意 :端口后面要加上ssl才可生效
The ssl configuration was inspired by this article
2. A series of problems encountered
2.1. The h5 project is packaged and deployed to production
Mixed Content: The page at 'xxx' was loaded over HTTPS, but requested an insecure resource 'xxx'. This request has been blocked; the content must be served over HTTPS Problem solving explanation: When our browser appears similar to "was
loaded over HTTPS, but requested an insecure resource/frame" error is generally because our website is HTTPS, and the other party's link is HTTP protocol, so when Ajax or javascript requests, it will report the above Error, if requesting http interface or importing http resources in https will be directly blocked (blocked), the browser defaults to this behavior as unsafe and will block it.
Solution:
(在index.html的head中加入以下代码)
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
Function: The principle of adding this tag is to use the META tag to forcibly convert http requests into https (SSL protocol) requests.
Summarize
Always grow after constantly stepping on the pit! ! !