1. Cross-domain access
The Origin Header in the concept HTTP protocol exists in a request and is used to indicate which site the current request is coming from.
Origin contains only site information and does not contain any path information.
grammar
Origin: "" Origin: "<schema>://<host>[:port]" // Example: Origin: "https://baidu.com" // Error demonstration, containing path information Origin: "https://baidu.com/"Copy the code
Apply CORS When our browser makes a cross-site request, the properly behaved server verifies that the current request is from an approved site. The server uses the Origin field to determine the value.
When the server configuration error, such as the configuration of baidu.com, it may cause some unreasonable…
For example, some browsers (IE) can request success while others (Chrome) can’t. It’s not because the previous browser did the right thing, it’s because the previous browser didn’t put Origin on the request and the other browser put the right Origin on the request. On the server side, since there is no Origin Header, it is considered that this is not a CORS request, so CORS verification is not performed. This in turn requires the server to force the request with the Origin Header to further ensure the security of the server.
2. Why must the page add Origin source analysis
/** * This is the supported request header. If you have a custom header field, please add */
private static final String ALLOWED_HEADERS = "X-Requested-With, Tenant-Id, Blade-Auth, Content-Type, Authorization, credential, X-XSRF-TOKEN, token, username, client";
private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD";
private static final String ALLOWED_ORIGIN = "*";
private static final String ALLOWED_EXPOSE = "*";
private static final String MAX_AGE = "18000L";
/** * Cross-domain configuration */
@Bean
public WebFilter corsFilter(a) {
return (ServerWebExchange ctx, WebFilterChain chain) -> {
ServerHttpRequest request = ctx.getRequest();
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = ctx.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
headers.add("Access-Control-Max-Age", MAX_AGE);
headers.add("Access-Control-Allow-Credentials"."true");
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
returnMono.empty(); }}return chain.filter(ctx);
};
}
Copy the code
Calling this method determines:
public static boolean isCorsRequest(ServerHttpRequest request) {
return request.getHeaders().get("Origin") != null;
}
Copy the code
Note that this approach handles cross-domain access through the Gateway
Or you can use the following method:
@Configuration // gateway
public class GulimallCorsConfiguration {
@Bean // Add a filter
public CorsWebFilter corsWebFilter(a){
// Select reactive based on URL cross-domain
UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
// Cross-domain configuration information
CorsConfiguration corsConfiguration = new CorsConfiguration();
// Allow cross-domain headers
corsConfiguration.addAllowedHeader("*");
// Allow cross-domain requests
corsConfiguration.addAllowedMethod("*");
// Allow cross-domain request sources
corsConfiguration.addAllowedOrigin("*");
// Whether cookies can be carried across domains
corsConfiguration.setAllowCredentials(true);
// Any URL should be configured across domains
source.registerCorsConfiguration("/ * *",corsConfiguration);
return newCorsWebFilter(source); }}Copy the code
1.Cross-domain explain1.1How do I know that I have a cross-domain problem if the project didn't do the front and back end separation, there would be no cross-domain problem. Error No is reported when the front end invokes the background service in a project where the front end and the back end are separated'Access-Control-Allow-Origin'Header is present on the requested resource. In addition, the front end debugging wall crack is recommended to use Chrome, using QQ browser encountered cross-domain access but did not report an error pit dad event.1.2Why did the same origin policy of the browser reject our request? The same name, the same protocol, the same port, the same script will be executed when the browser executes the same script. If not, the browser will raise the above exception in the console when requesting data, prompting access to be denied. This is to protect your login information of A website from being used by B website to access A website when multiple websites are opened in the same browser. The login information of B website is the same.1.3How to Solve cross-domain problems The articles on the web are very detailed on how to solve cross-domain problems. But most of the cross-domain solutions using Nginx are written in less detail or in so much detail that there are too many distractions, which can be misleading. So here's a summary.2.Use Nginx to solve cross-domain problems2.1First of all, I want to clarify a few concepts. The front-end project, the back-end project, and nginx are the three server projects. They just communicate with each other. Each of the three projects has its own IP: port combination. Even if you start the three servers on the same server, their ports will not be the same. As a result, front-end projects, whether accessing Nginx or back-end projects, can cause cross-domain problems.2.2The following examples are all projects on the same machine, so the IP address is the same. Front-end projects are differentiated only by port (8081), back-end projects (8082) and nginx (8080).2.21.methods1Address rewriting (or forwarding) is configured in nginx to access addresses that begin with /video_resource and are captured by this module and forwarded to HTTP://192.168.137.189:8082 back-end project go up. Go to http://192.168.137.189:8080/video_resource/userList/engineer at this time, for example, will be forwarded to http://192.168.137.189:8082/userList/engineer.Access addresses beginning with /js are also captured by the module and forwarded to HTTP://192.168.137.189:8082 front-end project up.
server
{
listen 8080; location /resource { rewrite ^/resource/? $/ $(. *)1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http:/ / 192.168.137.189:8082 /; # forwarding address} location /js { rewrite ^/js/? $/ $(. *)1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http:/ / 192.168.137.189:8081 /; # forwarding address}} At this point, the front-end and back-end projects are accessed through nginx, and the front-end projects are forwarded through /js identification, and the back-end projects are forwarded through /resource identification. The browser same origin policy records HTTP://192.168.137.189:8080/, the browser can only access the nginx 8080 address, and the cross-domain problem is solved.
2.22.methods2: added to nginx to allow cross-domain request headers server {listen8080; add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers X-Requested-With; add_header Access-Control-Allow-Methods GET,POST,OPTIONS; location /resource { rewrite ^/resource/? $/ $(. *)1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http:/ / 192.168.137.189:8082 /; # forwarding address}} This is the same as using nginx to allow cross-domain configuration in back-end projects (tomcat or server-side code written by myself), but putting the cross-domain configuration in nginx solves the cross-domain problem of front-end projects accessing Nginx. Nginx does not have cross-domain problems accessing back-end projects (not browsers, no same-origin policy restrictions). At this point nginx acts as a proxy distributor for the back end.3.If the same IP address: port is not the same as the same IP address: port, there is no cross-domain problem. If the same IP address: port is not the same, use nginx to tell the same IP address: port to access the same IP address: port, so that the same IP address: port is still accessed. The port.Copy the code
3. Use nginx to set up cross-domains
Nginx configuration (recommended) through the Nginx core idea, or any other generation tools, this is the address of the interface cross-domain agent to the local, and then call the local agent after the address, can solve the problem of cross-domain reference: www.jianshu.com/p/1080014a2…
conclusion
- It is convenient to configure cross-domains from the Gateway, and once configured, all other requests will be supported, but this will affect the performance of the system more or less, and in a deeper sense, this is not what the server should do
- Nginx reverse generation configuration mode, although it seems troublesome, requires cross-domain configuration everywhere, but because of the high performance of Nginx, after the API reverse proxy, there is no significant loss, but also in a way to reduce the pressure on the server. Therefore, it is recommended to use Nginx or other anti-generation tools to solve cross-domain problems.