vue 前端 springboot 后端分离跨域求解 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
madworks
V2EX    Java

vue 前端 springboot 后端分离跨域求解

  •  
  •   madworks 2020-10-27 14:51:27 +08:00 4342 次点击
    这是一个创建于 1814 天前的主题,其中的信息可能已经有所发展或是发生改变。
    上一周整合 springsecurity 写个项目,前端用 vue,302 跳转登录遇到跨域问题,一直无法解决,前后端都使劲浑身节数不得姐,不管用 @crossorigin,corsconfigaddorigin*、192168,前端设置 axiosCredentials,webpackproxy 都不行,求问怎么解决,还有问下大家是习惯 vue 前端打包后当成静态和后端放在一起运行,还分开运行
    41 条回复    2020-10-27 22:41:05 +08:00
    jiangnan01
        1
    jiangnan01  
       2020-10-27 14:59:17 +08:00
    接口用 postman 能通吗?如果能通,前端在开发环境配 proxy 应该也是可以的,不需要后端做任何事
    至于到底是分开运行还是放到一起,看项目怎么要求了,能分开更好
    madworks
        2
    madworks  
    OP
       2020-10-27 15:01:26 +08:00
    @jiangnan01 没有 postman,就是本地能用,用同事机器访问我 ip 项目不能
    jiangnan01
        3
    jiangnan01  
       2020-10-27 15:04:31 +08:00
    @madworks 你自己运行起来是前后端分开的还是放在一起的?同事访问的方式呢?
    madworks
        4
    madworks  
    OP
       2020-10-27 15:08:06 +08:00
    @jiangnan01 我自己访问是分开的,同事是访问我项目前端。而且我们另一个 vue 开发的项目发现 webpack 代理那里不能用 ip,必须写域名
    OldActorsSmile
        5
    OldActorsSmile  
       2020-10-27 15:09:17 +08:00
    服务端 header 里配置允许跨域就好了,你看高德的 api,跨域调用它都没问题
    OldActorsSmile
        6
    OldActorsSmile  
       2020-10-27 15:10:15 +08:00
    JAVA 我不熟,php 是这样写的:
    header('Access-Control-Allow-Origin:*'); // *代表允许任何网址请求
    hafuhafu
        7
    hafuhafu  
       2020-10-27 15:12:17 +08:00
    盲猜可能是复杂请求没处理 OPTIONS 吧,跨域是浏览器的行为,如果接口本身是正常的,postman 不会管跨不跨域,定能通的。
    ljpCN
        8
    ljpCN  
       2020-10-27 15:12:40 +08:00 via Android
    建议贴上完整的前端域名和 http 请求信息
    madworks
        9
    madworks  
    OP
       2020-10-27 15:13:58 +08:00
    @OldActorsSmile 这个我写过,不行好像
    anonydmer
        10
    anonydmer  
       2020-10-27 15:14:14 +08:00
    搞不定就搞个 nginx 代理下,去掉跨域啦
    madworks
        11
    madworks  
    OP
       2020-10-27 15:15:25 +08:00
    @ljpCN 这个 springsecurity 代码里看到过,应该他内部已经做处理了
    jiangnan01
        12
    jiangnan01  
       2020-10-27 15:22:31 +08:00
    @madworks 你自己的前端项目配 proxy 了吗?
    madworks
        13
    madworks  
    OP
       2020-10-27 15:23:01 +08:00
    @jiangnan01 配了的
    OldActorsSmile
        14
    OldActorsSmile  
       2020-10-27 15:26:22 +08:00
    @madworks

    跨域的原理是浏览器为了安全而阻止。如果浏览器发现服务器 header 告诉它允许就可以。高德的 api 跨域就是这个原理。
    有图有真相,你试试: https://shoujihao.zhishifufei.cn/

    THESDZ
        15
    THESDZ  
       2020-10-27 15:54:29 +08:00
    1.本地调试,使用 proxyTable
    2.生产部署使用 nginx 反向代理到服务器 ip:port

    以上为本人解决方式,仅供参考
    NULL2020
        16
    NULL2020  
       2020-10-27 16:03:49 +08:00
    ```

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


    ```
    KuroNekoFan
        17
    KuroNekoFan  
       2020-10-27 16:05:28 +08:00
    没啥必要就置同域吧
    madworks
        18
    madworks  
    OP
       2020-10-27 16:21:41 +08:00
    @NULL2020 这样写过,没用
    madworks
        19
    madworks  
    OP
       2020-10-27 16:22:25 +08:00
    @THESDZ 加了一层,这样做的目的是什么
    THESDZ
        20
    THESDZ  
       2020-10-27 16:28:23 +08:00
    @madworks 对于用户来说,前后端的资源请求在同一域内
    whatCanIDoForYou
        21
    whatCanIDoForYou  
       2020-10-27 16:39:25 +08:00
    三种解决办法:
    1,nginx 配置映射 (我没有实操过。。)
    2,前端处理(我是后端)
    3,后端处理
    搞一个 配置类 或者配置文件(我是类)具体代码如下:
    @Configuration
    public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Bean
    public CorsFilter corsFilter() {
    final UrlBasedCorsConfigurationSource urlBasedCorsCOnfigurationSource= new UrlBasedCorsConfigurationSource();
    final CorsConfiguration corsCOnfiguration= new CorsConfiguration();
    /*是否允许请求带有验证信息*/
    corsConfiguration.setAllowCredentials(true);
    /*允许访问的客户端域名*/
    corsConfiguration.addAllowedOrigin("*");
    /*允许服务端访问的客户端请求头*/
    corsConfiguration.addAllowedHeader("*");
    /*允许访问的方法名,GET POST 等*/
    corsConfiguration.addAllowedMethod("*");
    urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
    return new CorsFilter(urlBasedCorsConfigurationSource);
    }
    }
    wellsc
        22
    wellsc  
       2020-10-27 16:43:08 +08:00
    配个反向代理?
    yaphets666
        23
    yaphets666  
       2020-10-27 16:44:22 +08:00
    nginx 呀我的哥 webpack proxy 这就离谱了啊 这是前端自己启动 webpack-dev-server 开发的时候用的 执行 build 命令打包后的前端工程跟 webpack proxy 没关系了
    Sapp
        24
    Sapp  
       2020-10-27 16:45:07 +08:00   1
    1. 试试 postman 这种可能不能跑通,没有下载就写个 node 调用一下看能不能通,能跑通就不是接口本身有问题
    2. 观察一下看看是不是 get 可以,post 不行,可能是复杂请求没有处理 option 的问题,如果都不行就不是这个问题
    3. 服务器设置一下允许跨域看看行不行,按理说这个是终极解决方案
    4. 如果服务器设置了跨域还是不行,那就继续检查一下 2 看看是不是没处理 option,理论上来讲,到这个阶段怎么都调用通了
    Sapp
        25
    Sapp  
       2020-10-27 16:47:22 +08:00
    另外前端和后端是不是同域我觉得根本无所谓,现在跨域根本就不是个事,全看你们公司的架构怎么设计的前后端部署这一块。
    vision1900
        26
    vision1900  
       2020-10-27 16:49:01 +08:00
    前端用 Proxy
    或者后端用个跨域中间件,没必要自己写,规则没有那么简单
    Express 这个中间件是 cors,一行代码解决战斗
    lzhlzhlc123
        27
    lzhlzhlc123  
       2020-10-27 16:50:58 +08:00
    前端打包成静态之后可以使用 nginx 做静态资源代理代理
    可以在 nginx.conf 文件中下面添加 server 模块 ->server 模块中添加需要监听的端口号->server 中添加 location 模块中使用 root 和 index 做静态代理 location 中使用 proxy_set_header 做代理

    server {
    listen 85;
    location / {
    root /usr/local/app/hr/dist;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
    }

    location /api {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://localhost:8091/sxwendu;
    }
    }
    cco
        28
    cco  
       2020-10-27 16:51:22 +08:00
    @CrossOrigin 注解- -。
    lzhlzhlc123
        29
    lzhlzhlc123  
       2020-10-27 16:52:02 +08:00
    实在不行配合一下楼上兄弟的后端代码,基本可以解决大部分问题了
    clf
        30
    clf  
       2020-10-27 16:54:37 +08:00
    前端代理就行,百度 Vue-cli 代理一大堆文章教程,或者弄个 nginx 搞反向代理 /api/ 到后端的端口路径。

    还有一种方法是前端代码 build 到后端的目录里,用 SpringBoot 作为静态文件服务器。
    ClutchBear
        31
    ClutchBear  
       2020-10-27 17:17:16 +08:00
    spring security 好像是有自己的跨域解决方式:
    我是这样处理的
    在 SecurityConfig 中添加这个 bean
    ```
    /**
    * 跨域
    * https://lolico.me/2020/04/26/Spring-Security-CORS/
    * https://blog.csdn.net/Keith003/article/details/104221174
    *
    * @return
    */
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration cOnfiguration= new CorsConfiguration();
    configuration.addAllowedOrigin("*"); // 根据实际的需要去设置
    configuration.addAllowedMethod("*"); // 同上
    configuration.addAllowedHeader("*");
    configuration.setMaxAge(3600L);
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
    }
    ```

    然后在重写的 configure 方法中, 添加
    ```
    // 禁用 CSRF
    http.csrf().disable();
    // 禁用表单登录
    http.formLogin().disable();
    // 防止 iframe 造成跨域
    http.headers().frameOptions().disable();
    // 开启跨域
    http.cors();
    ```

    在实现 AuthenticationFailureHandler 接口的 handler 中添加
    ```
    // 跨域 options 请求直接返回
    if (Objects.equals(request.getMethod(), HttpMethod.OPTIONS.toString())) {
    return;
    }
    ```
    bob971683
        32
    bob971683  
       2020-10-27 17:24:24 +08:00
    同楼上,可以看下是不是请求的 OPTIONS 被验证拦截了
    hb0730
        33
    hb0730  
       2020-10-27 17:26:51 +08:00
    /**
    * 创建跨域 filter
    *
    * @return {@link CorsFilter}
    */
    @Bean
    public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource corsCOnfiguration= new UrlBasedCorsConfigurationSource();
    corsConfiguration.registerCorsConfiguration("/**", build());
    return new CorsFilter(corsConfiguration);
    }

    private CorsConfiguration build() {
    CorsConfiguration cOnfiguration= new CorsConfiguration();
    configuration.setAllowCredentials(true);
    configuration.addAllowedOrigin("*");
    configuration.addAllowedHeader("*");
    configuration.addAllowedMethod("*");
    configuration.addExposedHeader("content-disposition");
    configuration.setMaxAge(3600L);
    return configuration;
    }
    madworks
        34
    madworks  
    OP
       2020-10-27 18:18:34 +08:00
    @lzhlzhlc123 已收藏,不过暂时不想引入 nginx
    youla
        35
    youla  
       2020-10-27 18:25:17 +08:00
    如果是携带 cookies 跨域,应该不能这样写 Access-Control-Allow-Origin:*,要指定域名,如果有端口也要指定。

    如果不携带 cookies 跨域,axiosCredentials 设置为 false 就行了。
    lavvrence
        36
    lavvrence  
       2020-10-27 19:15:04 +08:00
    kekxv
        37
    kekxv  
       2020-10-27 19:19:38 +08:00 via iPhone
    有没有可能你请求的地址是 127.0.0.1
    Yourshell
        38
    Yourshell  
       2020-10-27 19:24:42 +08:00
    框架配置好后,你先单独请求看看响应带不带跨域头啊,没有不就证明框架配置有问题么。
    EminemW
        39
    EminemW  
       2020-10-27 22:22:06 +08:00
    首先跨域这玩意最好在 nginx 中配,不要侵入代码。。其次跨域头如果重复配,也会导致无法跨域,正常来说加这个 @crossorigin 注解就可以跨域的
    supuwoerc
        40
    supuwoerc  
       2020-10-27 22:39:57 +08:00
    webpack proxy 打完包就没有用了,这玩意是开发的时候用的。

    一般都是塞到后端程序的项目里面,如果要分开的话一般都是 Nginx 代理。
    supuwoerc
        41
    supuwoerc  
       2020-10-27 22:41:05 +08:00
    另外 postman 能通也没用。postman 又不是浏览器环境。

    跨域是浏览器的安全策略。postman 不存在这个策略。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2955 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 13:47 PVG 21:47 LAX 06:47 JFK 09:47
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86