axios跨域请求

14,900 阅读2分钟

axios跨域请求出现403。

一、nginx代理

一般情况下我们可以通过设置代理来解决跨域问题。给所有异步请求加一个前缀:

比如前端项目部署在8080端口(nginx),后端项目部署在8081端口。 后端提供有两个api:/class/student, /university/college。 前端在访问的时候访问8080端口的/api/class/student, /api/university/college,通过nginx拦截所有以api开头的请求,然后转发给8081端口。这样请求就没有跨域。

但是这样,其他人也可以通过访问8080端口的/api/class/student进而访问到8081端口。

二、跨域

1.前端axios配置

通过如下设置:

axios.defaults.crossDomain = true
//Access-Control-Allow-Origin 指向前端 ip:port
axios.defaults.headers.common['Access-Control-Allow-Origin'] = process.env.VUE_APP_Access_Control_Allow_Origin;

表示所有axios请求都是跨域请求,那么每次请求之前都会发送一个Options(预检)请求,用于询问后端是否允许本次请求。所以需要后端也进行相应的设置。

2.后端配置

后端需要配置一个拦截器,然后给响应添加响应头(包括Access-Control-Allow_Origin[指向前端 ip:port]、Access-Control-Allow-Headers、Access-Control-Allow-Methods)

SpringBoot示例:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Value("${ip-port}")
    private String ipPort;

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //跨域配置   允许所有端口访问
        //跨域配置,不可设置为*,不安全, 前后端分离项目,可能域名不一致
        //本地测试 端口不一致 也算跨域
        registry.addMapping("/**")
                .allowedOrigins(ipPort)
                .allowedMethods("*")
                .allowCredentials(true);
    }
}

Node的express框架示例:


const app=require('express')()

app.all("*",function(req,res,next){
    //输出请求参数
    let data=''
    if (req.method==='GET'){
        data=JSON.stringify(req.query)
    }else {
        data=JSON.stringify(req.body)
    }
    console.log(`${req.path} : ${data}`)

    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin","*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers","content-type");
    //跨域允许的请求方式
    res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
    // 设置返回数据格式为json
    res.header('Content-Type', 'application/json')
    if (req.method.toLowerCase() === 'options')
        res.send(200);  //让options尝试请求快速结束
    else
        next();
})

注意:当前端需要把cookies也发送出去的时候,需要添加withCredentials。如下对axios进行封装:

const service = axios.create({
    // baseURL: '/api',
    baseURL: '',
    withCredentials: true,
    timeout: 10000
})

此时后端也需要对此进行设置(例如SpringBoot中allowCredentials(true)),并且此种情况下响应头的Access-Control-Allow-Origin字段不能为'*'(也要注意慎用localhost