8 способов решения междоменных проблем, включая шлюз, Nginx и SpringBoot~
8 способов решения междоменных проблем, включая шлюз, Nginx и SpringBoot~

Междоменная проблема заключается в том, что для защиты информационной безопасности пользователя браузер реализует политику одинакового происхождения, которая позволяет странице запрашивать ресурсы только из одного и того же источника (тот же протокол, имя домена и порт при запросе). инициируется пересечениями JavaScript. Политика одинакового происхождения означает, что, если цель запроса не соответствует имени домена, порту и протоколу текущей страницы, браузер предотвратит отправку или получение запроса.

Решение междоменных проблем

Междоменные проблемы можно решить с помощью следующих аспектов:

  1. Решение уровня приложения:Например Spring Boot Решайте междоменные проблемы в проектах.
  2. Обратное прокси-решение:Например Nginx решать междоменные проблемы.
  3. Решено в шлюзе:Например Spring Cloud Gateway решать междоменные проблемы.

Эти 3 типа решений включают в себя в общей сложности 8 решений, давайте рассмотрим их вместе.

1. Решение междоменных проблем в Spring Boot

В Spring Boot есть следующие 5 решений междоменных проблем:

  1. Используйте аннотацию @CrossOrigin для достижения междоменного [междоменного локального класса]
  2. Обеспечьте междоменный доступ через файлы конфигурации [глобальный междоменный]
  3. Достижение междоменного [глобального междоменного доступа] через объект CorsFilter
  4. Достижение междоменного доступа через объект Response [локальный междоменный метод]
  5. Достигните междоменного [глобального междоменного] внедрения ResponseBodyAdvice.

Давайте рассмотрим это подробно далее.

1.1 Междоменное использование аннотаций

Междоменный подход можно легко реализовать с помощью аннотации @CrossOrigin. Эта аннотация может изменять как классы, так и методы. Когда класс изменяется, это означает, что все интерфейсы в этом классе могут пересекать домены; когда метод изменяется, это означает, что этот метод может пересекать домены. Его реализация следующая:

Язык кода:java
копировать
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", "");
        }};
    }
}

Результат выполнения приведенного выше кода показан на рисунке ниже:

Как видно из рисунка выше, фронтенд-проект успешно обращается к другому бекенд-проекту, а это значит, что он решает междоменную проблему.

Анализ преимуществ и недостатков

Хотя этим методом достигается (Междоменный домен) относительно просто,Но осторожные друзья тоже могут его найти.,Этот метод может обеспечить только частичную междоменность. Если в проекте несколько классов, использовать этот метод будет сложнее (вам необходимо добавить эту аннотацию ко всем классам).

1.2 Междоменный доступ через файлы конфигурации

Глобального междоменного доступа можно добиться путем настройки файлов конфигурации. Шаги реализации следующие:

  • Создайте новый профиль.
  • Добавьте аннотацию @Configuration для реализации интерфейса WebMvcConfigurer.
  • Переопределите метод addCorsMappings, чтобы установить разрешенный междоменный код.

Конкретный код реализации выглядит следующим образом:

Язык кода:java
копировать
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("*");
    }
}

1.3 Междоменный доступ через CorsFilter

Эта реализация аналогична предыдущей реализации.,Он также может обеспечить глобальную междоменную,его Конкретный код реализации выглядит следующим образом:

Язык кода:java
копировать
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);
    }
}

1.4 Междоменный обмен данными через ответ

Этот метод является наиболее примитивным способом решения междоменных задач, но он может поддерживать любые Spring Boot версия (ранняя Spring Boot версия также поддерживается). Но этот метод также является частичным. домен, имеет наименьшую область применения и установлен на уровне метода Междоменный домен,его Конкретный код реализации выглядит следующим образом:

Язык кода:java
копировать
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", "");
        }};
    }
}

1.5 Междоменный доступ через ResponseBodyAdvice

переписывая ResponseBodyAdvice в интерфейсе beforeBodyWrite (возврат перед перезаписью), мы можем Междоменный для всех интерфейсов доменSET, ЭТО КОНКРЕТНЫЙ код реализации выглядит следующим образом:

Язык кода:java
копировать
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;
    }
}

Эта реализация также является глобальной и междоменной и действует для всех интерфейсов всего проекта.

2. Решение междоменных проблем в Nginx

Добавьте следующий код в файл конфигурации сервера Nginx:

Язык кода:shell
копировать
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 в конфигурации используется для установки заголовков ответов. К часто используемым заголовкам ответов относятся следующие:

  • Access-Control-Allow-Origin:используется для указания Разрешить Междоменный Доменное имя домена может быть установлено на * Указывает, что доступ ко всем доменным именам разрешен.
  • Access-Control-Allow-Methods:используется для указаниядопустимый Междоменный домен Запрошенный метод,Например GET、POST、OPTIONS ждать.
  • Access-Control-Allow-Headers:используется для указаниядопустимый Междоменный Настройка, запрошенная доменом Header。
  • Access-Control-Allow-Credentials:используется для указанияли Разрешить Междоменный домен Отправленные и полученные запросы Cookie。
  • Access-Control-Max-Age:Используется для настройки предполетных запросов(OPTIONS запрос) время кэширования ответа. 3. Решено в шлюзе Междоменный доменSpring Cloud Gateway Решение междоменных проблем может быть достигнуто двумя способами:
  1. Междоменная реализация настраивается в файле конфигурации. весна: облако: шлюз: Глобалкорс: CorsКонфигурации: '[/**]': # Здесь '/**' означает, что он эффективен для всех маршрутов и при необходимости может быть настроен для конкретного пути. AllowOrigins: "*" # Разрешить все адреса источников, также можно указать конкретное доменное имя AllowMethods: # Разрешенные типы методов HTTP -ПОЛУЧАТЬ - ПОЧТА - ПОМЕЩАТЬ -УДАЛИТЬ - ПАРАМЕТРЫ AllowHeaders: "*" # Разрешить все заголовки запросов, вы также можете указать определенные заголовки запросов allowCredentials: true # Разрешить ли перенос учетных данных (cookies) maxAge: 3600 # Срок действия предполетного запроса CORS (секунды), где:
  2. Решите междоменные проблемы, добавив CorsWebFilter в платформу. 3.1 Междоменные настройки в файле конфигурации Добавьте следующую конфигурацию в файл application.yml или application.properties:
  • allowedOrigins: Установите список исходных доменных имен, к которым разрешен доступ, "*" Указывает, что разрешен любой источник.
  • allowedMethods: Указывает, какие методы HTTP можно использовать для запросов между источниками.
  • allowedHeaders: Список заголовков запросов, отправленных клиентом, "*" Указывает, что разрешен любой заголовок запроса.
  • allowCredentials: Если установлено значение true При инициировании междоменных запросов браузеру разрешено передавать аутентификационную информацию (например, cookies)。
  • maxAge: Максимальное время, в течение которого результаты предполетного запроса могут кэшироваться на клиенте.

При такой конфигурации Spring Cloud Gateway будет автоматически обрабатывать все проходящие через него междоменные запросы и добавлять соответствующие заголовки ответов, позволяя внешним приложениям выполнять междоменные запросы.

3.2 Добавьте CorsWebFilter для решения междоменных проблем

До версии Spring-Framework 5.3 используйте следующий код, чтобы разрешить Spring Cloud Gateway междоменный доступ:

Язык кода:java
копировать
@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, поэтому конфигурация становится следующей:

Язык кода:java
копировать
@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 лайков, обновил следующую статью, всем спасибо!

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose