跨域

跨域产生的原因

前后端分类项目,前端必然会向后端发送Ajax请求,若将前端和后端部署在同一服务器,那必然端口不一致、若不同服务器,不必然IP不一致,会产生跨域问题

基于浏览器的同源策略,去判断是否跨域请求,同源策略是浏览器的一种安全机制,从一个地址请求另一个地址,如果协议、主机、端口三者则不是跨域,否则就是跨域请求。 比如: 从http://localhost:8080 到 http://localhost:8081 由于端口不同,是跨域。 从http://192.168.101.10:8601 到 http://192.168.101.11:8601 由于主机不同,是跨域。 从http://192.168.101.10:8601 到 https://192.168.101.11:8601 由于协议不同,是跨域。

==注意:服务器之间不存在跨域请求。==

报错:

问题解决方案

一、微服务可以在网关中配置

spring:
  cloud:
    gateway:
      # 。。。
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求 
              - "http://localhost:8090"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

二、JSONP

通过script标签的src属性进行跨域请求,如果服务端要响应内容则首先读取请求参数callback的值,callback是一个回调函数的名称,服务端读取callback的值后将响应内容通过调用callback函数的方式告 诉请求方。如下图:

三、添加响应头

服务端在响应头添加 Access-Control-Allow-Origin:*

代码:
package com.itcast.system.config;

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;

/**
 * @ClassName: GlobalCorsConfig
 * @author: anqin
 * @Description: 过滤器解决跨域问题
 * @date: 2023/1/28 20:48
 */
@Configuration
public class GlobalCorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();

        //允许白名单域名进行跨域调用
        config.addAllowedOrigin("*");

        //允许跨越发送cookie
        config.setAllowCredentials(true);

        //放行全部原始头信息
        config.addAllowedHeader("*");

        //允许所有请求方法跨域调用
        config.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource cors = new UrlBasedCorsConfigurationSource();
        //  /** 代表表所有路径都拦截
        cors.registerCorsConfiguration("/**", config);
        return new CorsFilter(cors);
    }
}

四、通过nginx代理跨域

由于服务端之间没有跨域,浏览器通过nginx去访问跨域地址。

  • 浏览器先访问http://192.168.101.10:8601 nginx提供的地址,进入页面此页面要跨域访问http://192.168.101.11:8601 ,不能直接跨域访问http://www.baidu.com:8601,而是访问nginx的一个同源地址,比如:http://192.168.101.11:8601/api ,通过http://192.168.101.11:8601/api 的代理去访问http://www.baidu.com:8601。这样就实现了跨域访问。
  • 浏览器到http://192.168.101.11:8601/api 没有跨域
  • nginx到http://www.baidu.com:8601通过服务端通信,没有跨域。