当前位置: 欣欣网 > 码农

不要再问我跨域问题了,这篇文章全搞定

2024-06-04码农

跨域问题产生、原理、解决方案

文章导读

前言

跨域问题指的是在Web开发中,由于浏览器的 同源策略 限制,当一个网页尝试访问与它不同源( 协议、域名或端口不同 )的资源时,可能会遇到安全限制导致无法正常访问的问题。这种策略旨在防止恶意网站读取或修改其他网站的数据,保护用户信息安全。

这样说可能有点抽象,下面具体展开说明。

跨域问题演示

通常情况下,我们主流的开发模式是:前后端分离。当我们从浏览器80访问服务端81应用

下面我们用一个Web工程,一个后端工程具体简单演示下。

1、Web工程结构:

  • application.properties

  • spring.application.name=springboot-cross-web
    server.port=8080

  • index.html 页面

  • <!DOCTYPE html>
    <htmllang="en">
    <head>
    <metacharset="UTF-8">
    <metahttp-equiv="X-UA-Compatible"content="IE=edge">
    <metaname="viewport"content="width=device-width, initial-scale=1.0">
    <title>测试跨域请求页面</title>
    <scriptsrc="js/jquery-3.5.1.min.js"></script>
    </head>
    <body>
    <div>
    <inputtype="button"onclick="crossSubmit()"value="跨域测试">
    </div>
    <script>
    functioncrossSubmit() {
    // 发送跨域请求
    jQuery.ajax({
    url"http://localhost:8081/api/cross",
    type"POST",
    data: {"key""Cross"},
    successfunction (result{
    alert("返回数据:" + result.data);
    }
    });
    }
    </script>
    </body>
    </html>

    2、后端工程结构:

  • application.properties

  • spring.application.name=springboot-cross
    server.port=8081

  • 测试应用


  • @RestController
    public classCrossAppController{
    @RequestMapping("/api/cross")
    public HashMap<String, Object> crossTest(){
    returnnew HashMap<String, Object>() {{
    put("state", 200);
    put("data", "success");
    }};
    }
    }

    3、启动并测试

    浏览器报错产生跨域问题。

    为什么产生跨域问题?

    一般来讲,通常产生跨域问题有以下几种原因:

    1. 协议不同:如 https和http;

    2. 端口不同

    3. 域名不同

    这就是常说的 同源策略 的问题。产生跨域问题的根源就是请求不同源。

    如何解决跨域问题?

    从上边的问题来看,主要在于浏览器保护,对参数 "Access-Control-Allow-Origin" 的设置。

    主要有下解决方案:

    一、使用@CrossOrigin注解

    @RestController
    @CrossOrigin(origins = "*")
    public classCrossAppController{
    @RequestMapping("/api/cross")
    public HashMap<String, Object> crossTest(){
    returnnew HashMap<String, Object>() {{
    put("state", 200);
    put("data", "success");
    }};
    }
    }

    演示结果:

    二、使用全局跨域配置

    @Configuration
    public classWebConfigimplementsWebMvcConfigurer{
    @Override
    publicvoidaddCorsMappings(CorsRegistry registry){
    registry.addMapping("/api/cross")
    .allowedOrigins("*")
    .allowedMethods("GET""POST""PUT""DELETE")
    .allowedHeaders("*");
    //.allowCredentials(true);
    }
    }

    三、使用CorsFilter跨域

    @Component
    public classCorsFilterimplementsFilter{
    @Override
    publicvoiddoFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    HttpServletRequest request = (HttpServletRequest) req;
    // 设置允许的来源
    response.setHeader("Access-Control-Allow-Origin""*");
    // 处理预检请求
    if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
    response.setStatus(HttpServletResponse.SC_OK);
    else {
    chain.doFilter(req, res);
    }
    }
    }

    四、使用Nginx来实现跨域

    server {
    listen 80;
    server_name your.domain.com;
    location / {
    # 添加CORS相关的响应头
    add_header 'Access-Control-Allow-Origin''*';
    add_header 'Access-Control-Allow-Methods''GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers''DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
    # 对于OPTIONS请求,直接返回204状态码
    if ($request_method = 'OPTIONS') {
    return 204;
    }
    # 其他配置...
    # 代理到后端服务或其他配置...
    # proxy_pass http://your_backend/;
    # 其他proxy_...指令...
    }
    }



    总结

  • 跨域问题指的是在Web开发中,由于浏览器的 同源策略 限制,导致无法正常访问的问题。

  • 主要原理就是请求参数 Access-Control-Allow-Origin



  • 👇🏻 点击下方阅读原文,获取鱼皮往期编程干货。

    往期推荐