处理vue与后端的跨域问题

修改端口 为了端口不冲突

package.json—— “serve”: “vue-cli-service serve --port=80”,

在这里插入图片描述

形成跨域:

  1. 协议是否一样
  2. 服务器的ip是否一样
  3. 端口是否一样

上面三个只要有一个不一样, 形成跨域

处理跨域

  1. 前台解决:配置代理服务器
//后台服务器 代理服务器解决跨域问题
  devServer: {
    //后台服务器协议+端口
    proxy: {
      '/api': {//api替代url
        target: 'http://localhost:8888',
        ws: false,
        changeOrigin:true,//支持跨域请求
  }
    }
  }

发送的请求加 /api前缀

login() {
                    //前端解决跨域
            this.$http.get("/api/vuelogin?user=zhangsan&password=123")
                .then(function (response) {
                    //处理成功情况
                    console.log(response)
                })
                .catch(function (error) {
                    //处理错误情况
                    console.log(error);
                })
        }
  1. 后台解决:配置处理跨越的过滤器
@WebFilter(filterName = "CrossFilter",urlPatterns = "/*")
public class CrossFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*"); //允许所有的域名访问
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, PATCH, DELETE"); //允许的提交方式
        response.setHeader("Access-Control-Max-Age", "3600"); //最大有效时间
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type, Accept, Origin"); //允许那些请求头
        response.setHeader("Access-Control-Allow-Credentials", "true"); //是否支持ajax提交cookie
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}

3.使用nginx,其他的服务器处理跨域


实际开发中:确定api文档,统一响应数据格式

验证

在这里插入图片描述

//    禁止序列化密码
    @JSONField(serialize = false)
    private String password;

在这里插入图片描述

统一响应数据格式后 前端返回的数据

在这里插入图片描述

login(){
                    //后端解决跨域
var that = this; // 函数内的this指向函数 没有指向data
            that.$axios.get("http://localhost:8888/api/vuelogin?user=" + that.username + "&password=" + that.password)
                .then(function (response) {
                    console.log(response)
                    //处理成功情况
                
  // response.data.meta.status === 200  
 //1.const res = response.data return res响应拦截器  2. === 数据类型也要相同
                       
                    if (response.meta.status === 200) {
                        //保持token到本地
                        let admin = response.data;
                        localStorage.setItem("token", admin.username);

                        //跳转页面
                        that.$router.push({
                            name: 'home',
                            query: {
                                username: admin.username
                            }
                        });
                    } else {
                        that.user = "";
                        that.password = "";
                        alert(response.meta.msg);
                    }
                })
                .catch(function (error) {
                    //处理错误情况
                    console.log(error);
                    alert("服务器出错..")
                })
        }

跳转页面获取参数

<h1>{{username}}</h1>

computed: {
    username() {
      // 函数内加this
      return this.$route.query.username;
    }
  }

问题:post请求 参数不能跟在请求路径后

注意:

axios 发送请求, 使用请求体发送请求参数, 以json形式传递给服务器

request.getParameter("user") //要求请求参数是key/value对的方式

utils.request.js

import axios from 'axios'
import qs from 'qs'
/**
 * axios的传参方式:
 * 1.url 传参 一般用于Get和Delete 实现方式:config.params={JSON}
 * 2.body传参 实现方式:config.data = {JSON},且请求头为:headers: { 'Content-Type': 'application/json;charset=UTF-8' }
 * 3.表单传参 实现方式:config.data = qs.stringify({JSON}),且请求头为:且请求头为:headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }
 */
// axios实例
const $http = axios.create({
	baseURL: 'http://localhost:8888/api/',
    timeout: 60000,
	headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }
})
 
// 请求拦截器
$http.interceptors.request.use(
	(config) => {
		// 追加时间戳,防止GET请求缓存
		if (config.method?.toUpperCase() === 'GET') {
			config.params = { ...config.params, t: new Date().getTime() }
		}
		//如果是post qs将json转成key/value
		if (Object.values(config.headers).includes('application/x-www-form-urlencoded')) {
			config.data = qs.stringify(config.data)
		}
		return config
	},
	error => {
		return Promise.reject(error)
	}
)
 
// 响应拦截器
$http.interceptors.response.use(
	response => {
		const res = response.data
		return res
	},
	error => {
		return Promise.reject(error)
	}
)
 
// 导出 axios 实例
export default $http

main.js

 import $http from './utils/request'

//globalProperties 全局  app的全局属性名为$axios 
app.config.globalProperties.$axios = $http;
login(){
       //后端解决跨域
            var that = this; // 函数内的this指向函数 没有指向data
            that.$axios.post("vuelogin", {
                username: that.username,
                password:that.password
            })
                .then(function (response) {
                    console.log(response)
                    //处理成功情况
                    // response.data.meta.status === 200  
                    //1.const res = response.data return res响应拦截器  2. === 数据类型也要相同
                    if (response.meta.status === 200) {
                        //保持token到本地
                        let admin = response.data;
                        localStorage.setItem("token", admin.username);

                        //跳转页面
                        that.$router.push({
                            name: 'home',
                            query: {
                                username: admin.username
                            }
                        });
                    } else {
                        that.user = "";
                        that.password = "";
                        alert(response.meta.msg);
                    }
                })
                .catch(function (error) {
                    //处理错误情况
                    console.log(error);
                    alert("服务器出错..")
                })
        }

删除token

          alert(response.meta.msg);
                    }
                })
                .catch(function (error) {
                    //处理错误情况
                    console.log(error);
                    alert("服务器出错..")
                })
        }

在这里插入图片描述

验证码

加了验证码
在这里插入图片描述

在这里插入图片描述

原因:验证码更新

使用session,创建session对象把JSessionId 以cookie的形式保存在客户端浏览器。 没有携带cookieID ,会再次使用session

axios默认不携带cookie

解决:在request.js或main.js中

//CROS跨域是否允许凭证
$http.defaults.withCredentials = true; 

request.js 表单登录 key/value

	headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }

在这里插入图片描述

CrossFilter

 HttpServletRequest request = (HttpServletRequest) req;
      //  response.setHeader("Access-Control-Allow-Origin", "*"); //允许所有的域名访问
        //axios允许携带cookie Access-Control-Allow-Origin"不能设置为 "*"
        //设置为携带cookie的前端域名"https://localhost"
        //动态获取request.getHeader("origin")
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue中打开后端返回的跨域链接,需要在后端设置CORS(Cross-Origin Resource Sharing)跨域资源共享。CORS是一种机制,允许Web应用程序从不同的域访问其资源。如果你要打开的链接所在的域与你的Vue应用所在的域不同,就需要在后端设置CORS,允许跨域访问。 下面是一个简单的例子,展示如何在Express.js中设置CORS: ``` const express = require('express'); const app = express(); // 设置允许跨域访问的域名和方法 app.use(function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); res.setHeader('Access-Control-Allow-Credentials', true); next(); }); // 处理路由 app.get('/', function(req, res) { res.send('Hello World!'); }); // 启动服务 app.listen(3000, function() { console.log('Example app listening on port 3000!'); }); ``` 在上述代码中,我们使用了Express.js来创建一个简单的服务器,并使用app.use()方法来设置CORS。这里我们设置了允许所有域名(*)进行跨域访问,并允许GET、POST、OPTIONS、PUT、PATCH和DELETE方法,同时也允许携带cookie信息。当我们在Vue中打开后端返回的跨域链接时,就可以正常访问了。 需要注意的是,安全起见,应该尽可能地限制允许跨域访问的域名和方法,避免出现安全问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值