专栏名称: 程序员鱼皮
鹅厂全栈开发,持续分享编程技法和实用项目
目录
相关文章推荐
深圳大件事  ·  抖音、快手、微信同日公告! ·  昨天  
深圳大件事  ·  这宝石犹如彩虹,美得惊艳! ·  2 天前  
深圳大件事  ·  数额特别巨大!深圳一男子被判10年 ·  3 天前  
深圳大件事  ·  《哪吒2》登顶,中国动画审美就是牛! ·  3 天前  
51好读  ›  专栏  ›  程序员鱼皮

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

程序员鱼皮  · 公众号  ·  · 2024-06-04 13:30

正文

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

文章导读

前言

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

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

跨域问题演示

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

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

1、Web工程结构:

  • application.properties
spring.application.name=springboot-cross-web
server.port=8080
  • index.html 页面
html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试跨域请求页面title>
    <script src="js/jquery-3.5.1.min.js">script>
head>
<body>
<div>
    <input type="button" onclick="crossSubmit()" value="跨域测试">
div>
<script>
    function crossSubmit({
        // 发送跨域请求
        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 class CrossAppController {

    @RequestMapping("/api/cross")
    public HashMap crossTest() {
        return new HashMap() {{
            put("state", 200);
            put("data", "success");
        }};
    }
}

3、启动并测试

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

为什么产生跨域问题?

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

  1. 协议不同:如 https和http;
  2. 端口不同
  3. 域名不同

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

如何解决跨域问题?

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

主要有下解决方案:

一、使用@CrossOrigin注解

@RestController
@CrossOrigin(origins = "*")
public class CrossAppController {

    @RequestMapping("/api/cross")
    public HashMap crossTest() {
        return new HashMap() {{
            put("state", 200);
            put("data", "success");
        }};
    }
}

演示结果:

二、使用全局跨域配置

@Configuration
public class WebConfig implements WebMvcConfigurer {

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

三、使用CorsFilter跨域

@Component
public class CorsFilter implements Filter {

    @Override
    public void doFilter(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_...指令...  
    }  
}

总结







请到「今天看啥」查看全文


推荐文章
深圳大件事  ·  抖音、快手、微信同日公告!
昨天
深圳大件事  ·  这宝石犹如彩虹,美得惊艳!
2 天前
深圳大件事  ·  数额特别巨大!深圳一男子被判10年
3 天前
半导体行业观察  ·  全球半导体的2017布局盘点,都在忙活啥?
7 年前
创业投资最前线  ·  企业若做不到这一点,一切互撕都是扯淡!
7 年前
天才宝宝育儿  ·  婚姻里有多少女人被炼成了泼妇
7 年前