Varias soluciones de back-end para problemas de dominios cruzados de Java

Solución de problemas de dominios cruzados de Java

1. ¿Qué es el dominio cruzado?

Cross-domain se refiere a: los navegadores no pueden ejecutar scripts de otros sitios web, y cuando solicitan recursos de otro nombre de dominio desde una página web de un nombre de dominio, cualquier diferencia en el nombre de dominio, puerto o protocolo es cross-domain. El cruce de dominios es causado por la política del mismo origen del navegador, que es una restricción de seguridad impuesta por el navegador. La página A quiere obtener los recursos de la página B. Si los protocolos, los nombres de dominio, los puertos y los nombres de subdominio de las páginas A y B son diferentes, las acciones de acceso realizadas son todas entre dominios.

2. Ejemplos comunes de dominios cruzados

URL de la página actual URL de la página solicitada Ya sea entre dominios razón
http://www.test.com/ http://www.test.com/index.html No Misma fuente (mismo protocolo, nombre de dominio, número de puerto)
http://www.test.com/ https://www.test.com/index.html dominio cruzado El protocolo es diferente (http/https)
http://www.test.com/ http://www.baidu.com/ dominio cruzado El nombre de dominio es diferente (prueba/baidu)
http://www.test.com/ http://blog.test.com/ dominio cruzado El nombre de dominio es diferente (www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ dominio cruzado Diferentes números de puerto (8080/7001)

3. Solución de back-end de Java

1. Implementar WebMvcConfigurer

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    
    

    @Override
    public void addCorsMappings(CorsRegistry registry) {
    
    
        registry.addMapping("/**")// 拦截所有的请求
            .allowedOrigins("*")// 可跨域的域名,*为所有
            .allowCredentials(true)
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允许跨域的方法,可以单独配置
            .maxAge(3600);
    }
}

2. Interceptor del manipulador de implementos

Cree una clase que implemente la interfaz HandlerInterceptor y configure el encabezado de respuesta en el método preHandle para lograr un dominio cruzado.

@Component
public class CorsInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        response.setHeader("Access-Control-Allow-Origin", "http://example.com");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        return true;
    }
    // ...
}
```

这将允许来自 http://example.com 的跨域请求访问应用程序中的 API。

3. Usar filtro

Cree una clase que implemente la interfaz javax.servlet.Filter y configure el encabezado de respuesta en el método doFilter para lograr un dominio cruzado.

@WebFilter
public class CorsFilter implements Filter {
    
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    
    
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "http://example.com");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(req, res);
    }
    // ...
}
````

这将允许来自 http://example.com 的跨域请求访问应用程序中的 API。

Nota : cuando se usa Filter para implementar cross-domain, Filter interceptará todas las solicitudes, no solo las de cross-domain. Por lo tanto, debe tener cuidado al configurar encabezados de respuesta para evitar afectar el procesamiento normal de otras solicitudes. Si se requiere un control más detallado, considere usar la anotación o los interceptores @CrossOrigin.

4. Use la anotación @CrossOrigin para lograr

Al usar Spring Boot para implementar dominios cruzados, puede usar la anotación @CrossOrigin proporcionada por Spring para configurar el acceso entre dominios. Los pasos específicos de implementación son los siguientes:

(1) Agregue la anotación @CrossOrigin a la clase o método del controlador que necesita implementar el dominio cruzado. Por ejemplo:

@CrossOrigin(origins = "http://example.com")
@RestController
public class MyController {
    
    
    // ...
}
```

这将允许来自 http://example.com 的跨域请求访问 MyController 中的方法。

(2) Si es necesario permitir el acceso a varios nombres de dominio, el parámetro origins se puede establecer en una matriz que contenga todos los nombres de dominio a los que se permite el acceso. Por ejemplo:

@CrossOrigin(origins = {
    
    "http://example1.com", "http://example2.com"})
@RestController
public class MyController {
    
    
    // ...
}
```

(3) Si necesita permitir métodos HTTP entre dominios que no sean GET y POST, puede usar el parámetro de métodos para especificar la lista de métodos permitidos. Por ejemplo:

@CrossOrigin(origins = "http://example.com", methods = {
    
    RequestMethod.GET, RequestMethod.POST})
@RestController
public class MyController {
    
    
    // ...
}
```

(4) Si necesita permitir encabezados de solicitud entre dominios que no sean Content-Type, puede usar el parámetro allowHeaders para especificar la lista de encabezados de solicitud permitidos. Por ejemplo:

@CrossOrigin(origins = "http://example.com", allowedHeaders = {
    
    "Content-Type", "Authorization"})
@RestController
public class MyController {
    
    
    // ...
}
```

(5) Si necesita permitir el envío de información de autenticación, puede usar el parámetro allowCredentials para establecerlo en verdadero. Por ejemplo:

@CrossOrigin(origins = "http://example.com", allowCredentials = "true")
@RestController
public class MyController {
    
    
    // ...
}
```

5. Agregue campos como Access-Control-Allow-Origin en el encabezado de respuesta

(1) Agregue el campo Access-Control-Allow-Origin en el encabezado de respuesta para permitir el acceso de nombres de dominio específicos. Por ejemplo, el siguiente código permitirá que el nombre de dominio http://example.com acceda a la API:

response.setHeader("Access-Control-Allow-Origin", "http://example.com");
```
    
如果希望允许所有域名访问 API,可以将值设置为 *

(2) Si necesita permitir que varios nombres de dominio accedan a la API, puede agregar el campo Access-Control-Allow-Origin en el encabezado de respuesta y configurarlo en una lista que contenga todos los nombres de dominio a los que se les permite acceder. Por ejemplo:

response.setHeader("Access-Control-Allow-Origin", "http://example1.com, http://example2.com");
```

(3) Si necesita permitir métodos HTTP entre dominios que no sean GET y POST, puede agregar el campo Access-Control-Allow-Methods en el encabezado de respuesta para especificar la lista de métodos permitidos. Por ejemplo:

response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
```

(4) Si necesita permitir encabezados de solicitud entre dominios que no sean Content-Type, puede agregar el campo Access-Control-Allow-Headers en el encabezado de respuesta para especificar la lista de encabezados de solicitud permitidos. Por ejemplo:

response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
```

(5) Si utiliza una solicitud con información de autenticación, como una solicitud con Cookie, debe agregar el campo Access-Control-Allow-Credentials en el encabezado de respuesta y establecerlo en verdadero, lo que indica que la información de autenticación puede ser enviado Por ejemplo:

response.setHeader("Access-Control-Allow-Credentials", "true");
```

最后,需要将这些响应头添加到每个需要跨域访问的 API 的响应中。

6. Usa la configuración de Nginx

location / {
   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;

   if ($request_method = 'OPTIONS') {
     return 204;
   }
}

Si utiliza una solicitud con información de autenticación, como una solicitud con Cookie, debe configurar el campo Access-Control-Allow-Credentials en verdadero, lo que significa que se permite enviar información de autenticación. Por ejemplo:

add_header 'Access-Control-Allow-Credentials' 'true';

Si se usa el balanceo de carga en la parte superior de Nginx, la configuración anterior debe agregarse al bloque del servidor de balanceo de carga. Si se utiliza un proxy inverso, la configuración anterior también debe agregarse al bloque del servidor del proxy inverso.

7. Configurar el enrutamiento de la puerta de enlace

- id: my_route
  uri: http://localhost:8080
  predicates:
    - Path=/api/**
  filters:
    - RewritePath=/api/(?<segment>.*), /$\{
    
    segment}
    - AddResponseHeader=Access-Control-Allow-Origin:http://example.com
    - AddResponseHeader=Access-Control-Allow-Methods:GET, POST, PUT, DELETE
    - AddResponseHeader=Access-Control-Allow-Headers:Content-Type, Authorization
    - AddResponseHeader=Access-Control-Allow-Credentials:true
`````

这将允许来自 http://example.com 的跨域请求访问 Gateway 中的 API。

Si utiliza una solicitud con información de autenticación, como una solicitud con Cookie, debe configurar el campo Access-Control-Allow-Credentials en verdadero, lo que significa que se permite enviar información de autenticación. Por ejemplo:

- AddResponseHeader=Access-Control-Allow-Credentials:true
`````

最后,需要将这些配置添加到每个需要跨域访问的 API 的路由配置中。

需要注意的是,如果在 Gateway 的路由中使用了负载均衡,需要在负载均衡的路由配置中添加以上配置。如果使用了反向代理,也需要在反向代理的路由配置中添加以上配置。

Supongo que te gusta

Origin blog.csdn.net/dedede001/article/details/130503843
Recomendado
Clasificación