Междоменная проблема заключается в том, что для защиты информационной безопасности пользователя браузер реализует политику одинакового происхождения, которая позволяет странице запрашивать ресурсы только из одного и того же источника (тот же протокол, имя домена и порт при запросе). инициируется пересечениями JavaScript. Политика одинакового происхождения означает, что, если цель запроса не соответствует имени домена, порту и протоколу текущей страницы, браузер предотвратит отправку или получение запроса.
Междоменные проблемы можно решить с помощью следующих аспектов:
Эти 3 типа решений включают в себя в общей сложности 8 решений, давайте рассмотрим их вместе.
В Spring Boot есть следующие 5 решений междоменных проблем:
Давайте рассмотрим это подробно далее.
Междоменный подход можно легко реализовать с помощью аннотации @CrossOrigin. Эта аннотация может изменять как классы, так и методы. Когда класс изменяется, это означает, что все интерфейсы в этом классе могут пересекать домены; когда метод изменяется, это означает, что этот метод может пересекать домены. Его реализация следующая:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
@RestController
@CrossOrigin(origins = "*")
public class TestController {
@RequestMapping("/test")
public HashMap<String, Object> test() {
return new HashMap<String, Object>() {{
put("state", 200);
put("data", "success");
put("msg", "");
}};
}
}
Результат выполнения приведенного выше кода показан на рисунке ниже:
Как видно из рисунка выше, фронтенд-проект успешно обращается к другому бекенд-проекту, а это значит, что он решает междоменную проблему.
Анализ преимуществ и недостатков
Хотя этим методом достигается (Междоменный домен) относительно просто,Но осторожные друзья тоже могут его найти.,Этот метод может обеспечить только частичную междоменность. Если в проекте несколько классов, использовать этот метод будет сложнее (вам необходимо добавить эту аннотацию ко всем классам).
Глобального междоменного доступа можно добиться путем настройки файлов конфигурации. Шаги реализации следующие:
Конкретный код реализации выглядит следующим образом:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration // Обязательно не игнорируйте это замечание
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // Все интерфейсы
.allowCredentials(true) // Отправлять ли Cookie
.allowedOriginPatterns("*") // Поддержка домена
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"}) // Методы поддержки
.allowedHeaders("*")
.exposedHeaders("*");
}
}
Эта реализация аналогична предыдущей реализации.,Он также может обеспечить глобальную междоменную,его Конкретный код реализации выглядит следующим образом:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration // Эту аннотацию нельзя игнорировать
public class MyCorsFilter {
@Bean
public CorsFilter corsFilter() {
// 1.Создать CORS Объект конфигурации
CorsConfiguration config = new CorsConfiguration();
// Поддержка домена
config.addAllowedOriginPattern("*");
// Отправлять ли Cookie
config.setAllowCredentials(true);
// Метод запроса поддержки
config.addAllowedMethod("*");
// Допустимый Исходная информация заголовка запроса
config.addAllowedHeader("*");
// Открытая информация заголовка
config.addExposedHeader("*");
// 2.добавить Сопоставление адресов
UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
corsConfigurationSource.registerCorsConfiguration("/**", config);
// 3. Возврат CorsFilter объект
return new CorsFilter(corsConfigurationSource);
}
}
Этот метод является наиболее примитивным способом решения междоменных задач, но он может поддерживать любые Spring Boot версия (ранняя Spring Boot версия также поддерживается). Но этот метод также является частичным. домен, имеет наименьшую область применения и установлен на уровне метода Междоменный домен,его Конкретный код реализации выглядит следующим образом:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
@RestController
public class TestController {
@RequestMapping("/test")
public HashMap<String, Object> test(HttpServletResponse response) {
// Настройки Междоменный домен
response.setHeader("Access-Control-Allow-Origin", "*");
return new HashMap<String, Object>() {{
put("state", 200);
put("data", "success");
put("msg", "");
}};
}
}
переписывая ResponseBodyAdvice в интерфейсе beforeBodyWrite (возврат перед перезаписью), мы можем Междоменный для всех интерфейсов доменSET, ЭТО КОНКРЕТНЫЙ код реализации выглядит следующим образом:
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
/**
* Требуется ли перезапись контента (проходить Этот метод можно выполнить выборочно с помощью частичных контроллеров и методов перезаписи)
* возвращаться true выражатьпереписать */
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
/**
* Этот метод вызывается до того, как метод начнет
*/
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
// Настройки Междоменный домен
response.getHeaders().set("Access-Control-Allow-Origin", "*");
return body;
}
}
Эта реализация также является глобальной и междоменной и действует для всех интерфейсов всего проекта.
Добавьте следующий код в файл конфигурации сервера Nginx:
server {
listen 80;
server_name your_domain.com;
location /api {
# Разрешить Междоменный Доменное имя, запрошенное доменом,* Указывает, что доступ ко всем доменным именам разрешен.
add_header 'Access-Control-Allow-Origin' '*';
# Разрешить Междоменный домен Запрошенный метод
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# Разрешить Междоменный Настройка, запрошенная доменом Header
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';
# Разрешить Междоменный Запрошено доменом Credential
add_header 'Access-Control-Allow-Credentials' 'true';
# Время существования предполетного запроса, т.е. Options Запрошенное время кэширования ответа
add_header 'Access-Control-Max-Age' 3600;
# Обработка предполетных запросов
if ($request_method = 'OPTIONS') {
return 204;
}
}
# Другие конфигурации...
}
В приведенном выше примере местоположение /api представляет собой настройку междоменных параметров для запросов к пути /api. Значение местоположения и другие связанные параметры могут быть изменены в соответствии с конкретными потребностями. Директива add_header в конфигурации используется для установки заголовков ответов. К часто используемым заголовкам ответов относятся следующие:
При такой конфигурации Spring Cloud Gateway будет автоматически обрабатывать все проходящие через него междоменные запросы и добавлять соответствующие заголовки ответов, позволяя внешним приложениям выполнять междоменные запросы.
До версии Spring-Framework 5.3 используйте следующий код, чтобы разрешить Spring Cloud Gateway междоменный доступ:
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
// Это просто иллюстрация проблемы. Он настроен на освобождение всех доменных имен. Измените это в производственной среде.
config.addAllowedOrigin("*");
// Заголовок запроса на выпуск
config.addAllowedHeader("*");
// Тип запроса на выпуск, есть GET, POST, PUT, DELETE, OPTIONS
config.addAllowedMethod("*");
// Предоставление информации заголовка
config.addExposedHeader("*");
// Разрешить ли отправку Cookie
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
После Spring-Framework версии 5.3 имя метода addAllowedOrigin в классе междоменной конфигурации CORS CorsConfiguration изменяется на addAllowedOriginPattern, поэтому конфигурация становится следующей:
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
// Это просто иллюстрация проблемы. Он настроен на освобождение всех доменных имен. Измените это в производственной среде.
config.addAllowedOriginPattern("*");
// Заголовок запроса на выпуск
config.addAllowedHeader("*");
// Тип запроса на выпуск, есть GET, POST, PUT, DELETE, OPTIONS
config.addAllowedMethod("*");
// Предоставление информации заголовка
config.addExposedHeader("*");
// Разрешить ли отправку Cookie
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
Междоменные проблемы могут быть решены на уровне шлюза, обратном прокси-сервере или уровне приложения, а приоритет их использования следующий: Уровень шлюза. > прокси-слой > прикладной уровень. Потому что чем выше фронт, тем больше охват и тем легче решать междоменные проблемы.
Почему существует 8 решений междоменных проблем? Есть ли у этих 8 решений что-нибудь общее? Какова природа междоменных проблем?
Добро пожаловать в область комментариев, чтобы написать свой ответ. 50 лайков, обновил следующую статью, всем спасибо!