Vue使用axios跨域出错解决方案

Vue使用axios跨域出错解决方案

       在 Vue+SpringBoot 的前后端分离项目中,经常使用 axios 来解决跨域问题。但有时候配置错误,经常会出现问题,做登录模块时在下就遭了道!

前端 Vue 配置如下:

在config文件夹中的 index.js 文件中找到proxyTable属性,添加如下代码
在这里插入图片描述


		proxyTable: {
	        // 跨域支持
	        '/api': {
	            //后端接口地址
	            target: 'http://localhost:8443',
	            //接口跨域
	            changeOrigin: true,
	            //路径重写,实际请求中去掉/api以空字符串代替
	            pathRewrite: {
	                '^/api': ''
	            }
	        }
    	},
		// Various Dev Server settings
    	host: 'localhost', // can be overwritten by process.env.HOST
    	port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    	

main.js 中导入 axios(导入前当然要 npm install axios -S) 代码如下:

import axios from 'axios'
//使用axios, 解决前后台跨域问题, 后台地址
axios.defaults.baseURL = 'http://localhost:8443/api'
// 使请求带上凭证信息
axios.defaults.withCredentials = true
// 全局注册,之后可在其他组件中通过this.$axios发送数据
Vue.prototype.$axios = axios

前端的 Login.vue 中获取 Form中输入的用户名和密码, post 到后端。

	methods: {
		login() {
            this.$axios
                .post('/login', {
                    username: this.loginForm.username,
                    password: this.loginForm.password
                })
                .then(successResponse => {
                    if (successResponse.data.code === 200) {
                        this.$router.replace({path: '/home'})
                    }
                })
                .catch(failResponse => {
                })
        },
   }

后端 Springbootapplication.yml 文件中设置端口 server.port = 8443.

LoginController 获取传递数据,然后假判断一下(后期要用上数据库,暂且测试一下)

package com.lkq.pet.controller;


import com.lkq.pet.entity.Result;
import com.lkq.pet.entity.User;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;

import java.util.Objects;


/**
 * @author GoldenRetriever
 * @time 2020/10/5 21:47
 * @description
 */
@RestController
public class LoginController {


    @PostMapping(value = "api/login")
    @ResponseBody
    public Result login(@RequestBody User requestUser) {
        // 对 html 标签进行转义,防止 XSS 攻击
        String username = requestUser.getUsername();
        username = HtmlUtils.htmlEscape(username);

        if (!Objects.equals("admin", username) || !Objects.equals("123456", requestUser.getPassword())) {
            System.out.println("test");
            return new Result(400);
        } else {
            return new Result(200);
        }
    }

}

本来以为应该万事大吉,谁知道F12调试出现大问题:

在这里插入图片描述
错误:Access to XMLHttpRequest at ‘http://localhost:8443/api/login’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The value of the ‘Access-Control-Allow-Credentials’ header in the response is ‘’ which must be ‘true’ when the request’s credentials mode is ‘include’. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

解释:CORS 策略阻止了从源 http://localhost:8080 访问 http://localhost:8443/api/login 处的 XMLHttpRequest 。对预检请求的响应未通过访问控制检查:响应Access-Control-Allow-Credentials 头的值为空,而当请求的凭据模式为include时,它的值必须为 trueXMLHttpRequest发起的请求的凭据模式由 withCredentials 属性控制。

第一次解决方案:

LoginController 类上添加注解:

@CrossOrigin("http://localhost:8080")

       为什么说是第一次呢,因为后来我过段时间再次打开时,发现又不行了,当初测试的时候可是能通过的,就很气!

第二次解决方案

       气归气,bug还是要de的。百度找啊找啊,终于找到了缘由,真是众里寻他千百度啊!再结合CORS的解释,或许能解释的通了。

  1. 它说我Access-Control-Allow-Credentials 为空。
    网上说,它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
    (我是肯定没有使用Cookie啊!)
  2. 它说这个值一定要是 true。因为我的请求模式为 include
  3. 它最后又说,XMLHttpRequest发起的请求的凭据模式由 withCredentials 属性控制。
  4. 说得好像是我设置了withCredentials属性导致模式为include, 然后导致了前面的错误。
  5. 还真的是!!!

       记得我在main.js中设置的东西吗?

//使用axios, 解决前后台跨域问题, 后台地址
axios.defaults.baseURL = 'http://localhost:8443/api'
// 使请求带上凭证信息
axios.defaults.withCredentials = true
// 全局注册,之后可在其他组件中通过this.$axios发送数据
Vue.prototype.$axios = axios

找到了withCredentials 属性么?

//使用axios, 解决前后台跨域问题, 后台地址
axios.defaults.baseURL = 'http://localhost:8443/api'
// 使请求带上凭证信息
axios.defaults.withCredentials = false
// 全局注册,之后可在其他组件中通过this.$axios发送数据
Vue.prototype.$axios = axios

重新运行一下,ojbk。。。

总结一下,axios默认是请求不带上cookie,如果设置了withCredentials = true ,那么后端就要配合进行响应的设置:Head中 Access-Control-Allow-Credentials:true,如果像我一样不需要cookie,那么设置为false就行。莫要画蛇添足!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值