Axiso解决跨域访问

源码地址:https://github.com/jitwxs/blog_sample

首先请检查下你的 Vue 版本,Vue2 和 Vue3 跨域方式不同:

$ vue -V
2.X or 3.X

一、Vue2 版本

这里以访问 Ve2x 的一个公告API为例,直接访问如下:

this.$axios.get("https://www.v2ex.com/api/site/info.json")
.then(res=>{
    console.log(res)
})
.catch(err=>{
    console.log(err)
})

当我们运行程序后,控制台报错如下:
跨域访问错误
可以看到浏览器拦截了我们的请求,因为我们跨域了,下面解决跨域问题。

Step1:配置BaseUrl

首先在main.js中,配置下我们访问的Url前缀:

import Vue from 'vue'
import App from './App'
import Axios from 'axios'

Vue.prototype.$axios = Axios
Axios.defaults.baseURL = '/api'
Axios.defaults.headers.post['Content-Type'] = 'application/json';

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})

关键代码是:Axios.defaults.baseURL = '/api',这样每次发送请求都会带一个/api的前缀。

Step2:配置代理

修改config文件夹下的index.js文件,在proxyTable中加上如下代码:

'/api':{
    target: "https://www.v2ex.com/api",
    changeOrigin:true,
    pathRewrite:{
        '^/api':''
    }
}

配置代理

Step3:修改请求Url

修改刚刚的axios请求,把url修改如下:

this.$axios.get("/site/info.json")
.then(res=>{
	console.log(res)
})
.catch(err=>{
	console.log(err)
})

Step4:重启服务

重启服务后,此时已经能够访问了:

原理:

因为我们给url加上了前缀 /api,我们访问 http://127.0.0.1:19323/site/info.json 就当于访问了:http://127.0.0.1:19323/api/site/info.json。(假设本地访问端口号为 19323)

又因为在 index.js 中的 proxyTable 中拦截了 /api ,并把 /api 及其前面的所有替换成了 target 中的内容,因此实际访问 Url 是https://www.v2ex.com/api/site/info.json

二、Vue3 版本

升级到 Vue3 后,会发现 Vue2 中存放配置的 config 文件夹没有了,大家不要慌张。可以在 package.json 文件的同级目录下创建 vue.config.js 文件。给出该文件的基础配置:

module.exports = {
    outputDir: 'dist',   //build输出目录
    assetsDir: 'assets', //静态资源目录(js, css, img)
    lintOnSave: false, //是否开启eslint
    devServer: {
        open: true, //是否自动弹出浏览器页面
        host: "localhost", 
        port: '8081', 
        https: false,   //是否使用https协议
        hotOnly: false, //是否开启热更新
        proxy: null,
    }
}

vue.config.js

Vue3 解决跨域,内容只有第二步配置代理 和 Vue2 不同,其他的一致。

Step2:配置代理

修改 vue.config.js 中 devServer 子节点内容,添加一个 proxy

devServer: {
    open: true, //是否自动弹出浏览器页面
    host: "localhost", 
    port: '8081',
    https: false,
    hotOnly: false, 
    proxy: {
        '/api': {
            target: 'https://www.v2ex.com/api', //API服务器的地址
            changeOrigin: true,
            pathRewrite: {
                '^/api': ''
            }
        }
    },
}

三、番外

当然,跨域问题也可以由后端解决,将下面这个过滤器加入程序即可。

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 跨域过滤器
 * @author jitwxs
 * @since 2018/10/16 20:53
 */
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;

        // 不使用*,自动适配跨域域名,避免携带Cookie时失效
        String origin = request.getHeader("Origin");
        if(StringUtils.isNotBlank(origin)) {
            response.setHeader("Access-Control-Allow-Origin", origin);
        }

        // 自适应所有自定义头
        String headers = request.getHeader("Access-Control-Request-Headers");
        if(StringUtils.isNotBlank(headers)) {
            response.setHeader("Access-Control-Allow-Headers", headers);
            response.setHeader("Access-Control-Expose-Headers", headers);
        }

        // 允许跨域的请求方法类型
        response.setHeader("Access-Control-Allow-Methods", "*");
        // 预检命令(OPTIONS)缓存时间,单位:秒
        response.setHeader("Access-Control-Max-Age", "3600");
        // 明确许可客户端发送Cookie,不允许删除字段即可
        response.setHeader("Access-Control-Allow-Credentials", "true");
        
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) {

    }

    @Override
    public void destroy() {
    }

    /*
    注册过滤器:
    @Bean
    public FilterRegistrationBean registerFilter() {
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>();
        bean.addUrlPatterns("/*");
        bean.setFilter(new CorsFilter());
        // 过滤顺序,从小到大依次过滤
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);

        return bean;
    }
     */
}
### 处理纯HTML项目中的Axios CORS请求 在处理纯HTML项目中使用Axios发起HTTP请求时遇到的资源共享(CORS)问题,可以采取多种方法来解决问题。 #### 后端配置CORS头 为了允许来自不同源的请求,在服务器端设置响应头部是必要的措施之一。通过向响应添加特定的HTTP头部字段,能够告知浏览器哪些资源可以从其他访问。例如: ```go c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "GET, POST") [^1] ``` 这段代码展示了如何利用Go语言框架下的中间件函数为所有的响应附加`Access-Control-Allow-Origin`和`Access-Control-Allow-Methods`头部信息,从而支持任何来源(`*`)对该服务进行GET和POST类型的请求操作。 对于复杂的情况,当涉及到自定义首部或其他HTTP动词(如PUT、DELETE),则会在实际的数据传输之前先发出一个OPTIONS预检请求[^2]。此时还需要额外配置如下所示的相关参数以确保整个流程顺利执行: ```go c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization") c.Header("Access-Control-Max-Age", "86400") ``` 以上示例增加了对指定请求头的支持以及缓存时间的最大期限设定。 #### 使用代理服务器 另一种常见的解决方案是在开发环境中搭建本地代理服务器。这可以通过修改前端项目的构建工具配置实现,比如Vue CLI或React Create App都提供了内置的方式来进行简单的反向代理设置;而对于完全独立运行的静态网页,则可能需要借助Node.js这样的环境创建专门的服务程序作为中介层转发请求给目标API地址并接收返回的结果再传递回客户端应用[^4]。 #### 浏览器插件辅助调试 值得注意的是,在某些情况下,安装特定于浏览器扩展也可以暂时绕过同源策略限制以便更方便地测试接口调用逻辑,但这仅限于个人开发者用于学习目的而非生产部署方案的一部分考虑因素。 #### Axios实例默认配置调整 最后还可以尝试更改Axios全局选项或者单独针对某个请求对象增加属性来优化网络交互行为模式,特别是关于凭证携带方面的问题可能会引起不必要的麻烦所以要特别留意相关文档说明部分的内容指导实践操作过程中的细节之处。 ```javascript const instance = axios.create({ baseURL: 'https://example.com', timeout: 5000, withCredentials: false // 如果不需要带上cookie等认证信息可设为false,默认即为此值 }); ```
评论 53
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值