在我们平时写前后端分离项目的时候我们通常会遇到一个跨域的问题,跨域就是当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同
前端解决跨域方案:
在我们的vite.config.ts
文件中添加以下配置,我的后端路径是http://localhost:8080/JavaWeb/其他功能路径
server: {
hmr: true, //启动热更新,就是更改了代码自动刷新页面
port: 5173, //自定义启动时的端口,这个端口是前端的端口
proxy: {
'/JavaWeb': {//这里JavaWeb是我的后端路径,
target: 'http://localhost:8080',//这里是要代理的后端的协议,域名,端口
changeOrigin: true,
}
}
}
我这里前后端使用的是axios,配置了axios拦截器
import axios from "axios";
const request = axios.create({
baseURL: '/JavaWeb',//后端路径,这里配置之后后边发起请求的时候就可以直接在get或post方法的请求路径那里省掉这个公共的部分
timeout: 5000,//设置超时
headers: {'X-Custom-Header': 'foobar'}//设置请求头
});
// 添加请求拦截器
request.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
request.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});
//把配置好的axios导出
export default request;
我们配置了这个axios拦截器之后,我们后边发请求的时候,我们可以创建一个apis文件夹,把所有的api请求都放在这个文件夹下,
我们后边发请求就可以和下面这种一样写
//导入我们刚刚配置好的axios
import request from "@/util/request";
//导出一个login的方法
export let login = function (username: String, password: String) {
//login方法返回一个post请求,路径是/empServlet?action=login
//我们本来的请求路径是http://localhost:8080/JavaWeb/empServlet?action=login
//这里因为我们前边配置了拦截器和解决跨域的代理,所以这里就直接写后端的具体的功能的路径
//上边通过代理的方式解决跨域之后,后边如果出bug提示的请求路径就是http://localhost:5173/JavaWeb/empServlet?action=login
return request.post('/empServlet?action=login', null, {
params: {
username,
password
}
});
}
CV代码一定要仔细查看代码中的注释,后边再次请求报错如果出现什么路径问题不对劲的,在代码注释里面写了为什么路径不对劲CV代码一定要仔细查看代码中的注释,后边再次请求报错如果出现什么路径问题不对劲的,在代码注释里面写了为什么路径不对劲
CV代码一定要仔细查看代码中的注释,后边再次请求报错如果出现什么路径问题不对劲的,在代码注释里面写了为什么路径不对劲
重要的事情说三遍!!!
后端解决跨域方案:
方案一:
如果各位的项目是一个SpringBoot项目的话,大家可以直接在类前边添加一个@CrossOrigin
的注解
//使用restfull风格,这个注解合成了@ResponseBody和@Controller两个注解
//使用这个注解,如果在类上使用,该类的所有方法返回值都将以json格式返回,如果在方法上使用,则该方法以json格式返回,其他方法视图返回
@RestController
//设置该类中所有方法请求之前需要带的路径,例如,要请求/getList路径的方法,则需要在/getList之前加上/user---->/user/getList
@RequestMapping("/user")
//解决跨域问题,如果没有配置其内容,则所有的地址都可以访问
@CrossOrigin
public class UserController {
}
方案二:
我这个项目是servlet的,这里写了一个servlet的过滤器,在过滤器里面配置允许跨域
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hopu.domain.Result;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* Created by IntelliJ IDEA.
*
* @Author:YwaiX
* @version:1.0
* @Date:Created in 2024-08-07 14:54:53
* @Description:
*/
@WebFilter("/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//统一设置编码
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
/**
* 配置跨域
*/
HttpServletResponse res = (HttpServletResponse) response;
// 允许所有源访问
res.setHeader("Access-Control-Allow-Origin", "*");
// 允许的HTTP方法
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
// 允许的头信息字段
res.setHeader("Access-Control-Allow-Headers", "Content-Type, api_key, Authorization");
// 是否需要凭据
res.setHeader("Access-Control-Allow-Credentials", "true");
}
@Override
public void destroy() {
System.out.println("destory");
}
}