前后端分离项目,跨域问题解决方案

1、什么是跨域?

要了解跨域,先要说说同源策略。

同源策略是由 Netscape 公司提出的一个著名的安全策略,所有支持 JavaScript 的浏览器都会使用这个策略。

由于浏览器同源策略的限制,非同源下的请求,都会产生跨域问题,jsonp即是为了解决这个问题出现的一种简便解决方案。

同源策略即:同一协议,同一域名,同一端口号。当其中一个不满足时,我们的请求即会发生跨域问题。

一个系统访问另一个系统才会存在跨域,同系统访问不存在跨.

    跨域原因说明                                                 示例                               

   域名不同                                      www.jd.com 与 www.taobao.com      

  域名相同,端口不同                 www.jd.com:8080 与 www.jd.com:8081

  二级域名不同                                item.jd.com 与 miaosha.jd.com     

                                                 www.baidu.wenku.com 与 www.baidu.tieba.com

跨域不一定会有跨域问题

因为跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。

因此:跨域问题 是针对ajax请求的一种限制。只有发送ajax请求才会发生跨域问题。

2、解决跨域问题的方案

1、JSONP

        JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。

        核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

实现方式:

        原生实现:

<script src="http://test.com/data.php?callback=dosomething"></script>
// 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
 
// 处理服务器返回回调函数的数据
<script type="text/javascript">
    function dosomething(res){
        // 处理获得的数据
        console.log(res.data)
    }
</script>

   JQuery ajax实现: 

$.ajax({
    url: 'http://www.test.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp
    jsonpCallback: "handleCallback",    // 自定义回调函数名
    data: {}
});

  Vue.js 实现:

this.$http.jsonp('http://www.domain2.com:8080/login', {
    params: {},
    jsonp: 'handleCallback'
}).then((res) => {
    console.log(res); 
})

2、CORS(都可以使用-采纳)

  规范化的跨域请求解决方案,安全可靠

  优势:

  - 在服务端进行控制是否允许跨域,可自定义规则

  - 支持各种请求方式

  缺点:

  - 会产生额外的请求,要做询问

3、Nginx反向代理

        此方式是在部署前后端分离项目时最常使用的。具体看上一篇博客,有配置的详细介绍。

3、前后端分离的项目跨域解决方案实现

项目前端用的端口号是8081,后端用的是8080

1、方案一:后台解决方案

        编写一个CORS的跨域过滤器

package com.rk.pethome.basic.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;

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //1) 允许的域,不要写*,否则cookie就无法使用了
        config.addAllowedOrigin("http://127.0.0.1:8081");
        config.addAllowedOrigin("http://localhost:8081");
        //2) 是否发送Cookie信息
        config.setAllowCredentials(true);
        //3) 允许的请求方式
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        // 4)允许的头信息
        config.addAllowedHeader("*");
        //2.添加映射路径,我们拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new
                UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

        只需要修改允许前端的域就行,本项目前端端口使用的是8081 

        后端还有一种方案,给需要跨域访问的接口添加@CrossOrigin注解

        此时前端调用接口方式如下:

 //加载所有的部门列表
            loadAllDepartments(){
                this.$http.patch("http://localhost/department/loadAll").then((res => {
                    this.depts = res.data;
                }));
            },

2、方案二:前端解决方案

如果是前端开发,多个项目之间有相互访问的情况(只能在vue的项目可以解决)。

        1、在项目的config/index.js

proxyTable: {
    '/api': { //所有通过/api的请求都会代理到下面http://localhost:8080
        target: 'http://localhost:8080',
        //允许跨域
        changeOrigin: true,
        //移除url里面的api   /api/user/login 代理过来就行http://localhost:8080/user/login
        pathRewrite: {
            '^/api': '' 
        }
    }, 
},

        只需要修改后端项目端口,本项目后端端口使用的是8080

        2、在main.js中加入全局访问配置 为了不改变原来的访问,或者不需要每一次访问后台都要加上api.

//配置axios的全局基本路径
axios.defaults.baseURL='/api'

 配置完成后需要重启前端服务器才能生效。此方法类似于Nginx反向代理

此时前端调用接口,只需要接口名就行,如下

//加载所有的部门列表 
loadAllDepartments(){
    this.$http.patch("/department/loadAll").then((res => {
        this.depts = res.data;
    }));
},

  • 0
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rk..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值