• 【Vue】Vue之Axios跨域问题解决方案


    背景:因为axios中只能使用get和post方法来进行请求数据,没有提供jsonp等方法进行跨域访问数据

              axios中文网址:https://www.kancloud.cn/yunye/axios/234845

    // axios 中的GET请求
    axios.get('/user', {
        params: {
          ID: ‘001’
        }
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
     
    // axios 中的POST请求
    axios.post('/user', {
        firstName: '1',
        lastName: '2'
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });

    方案1:既然使用axios直接进行跨域访问不可行,我们就需要配置代理了。代理可以解决的原因:因为客户端请求服务端的数据是存在跨域问题的,而服务器和服务器之间可以相互请求数据,是没有跨域的概念(如果服务器没有设置禁止跨域的权限问题),也就是说,我们可以配置一个代理的服务器可以请求另一个服务器中的数据,然后把请求出来的数据返回到我们的代理服务器中,代理服务器再返回数据给我们的客户端,这样我们就可以实现跨域访问数据。

    准备工作:安装所需中间件和插件等,比如axios,http-proxy-middleware等。

    具体案例:这里以访问豆瓣Top250为例,直接访问如下:

    axios.get("http://api.douban.com/v2/movie/top250")
    .then(res=>{
        console.log(res)
    })
    .catch(err=>{
        console.log(err)
    })

    当执行npm run dev时,控制台报错如下:

     

    事实证明直接请求确实出现跨域问题了,下面具体演示解决跨域问题的步骤:

    上面所说的必备条件都已安装完成的情况下,执行以下步骤即可解决问题:

    1.配置BaseUrl

    在main.js中,配置数据所在服务器的前缀(即固定部分),代码如下:

    // 项目入口,配置全局vue
    import Vue from 'vue'
    import VueRouter from './router/routes.js'
    import Store from './store/index.js'
     
    import './assets/less/index.less'
    import App from './App.vue'
     
     
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-default/index.css'
     
    import axios from 'axios'
    Vue.prototype.$axios = axios
    axios.defaults.baseURL = '/api'  //关键代码
    Vue.config.productionTip = false
     
     
    Vue.use(ElementUI);
     
    new Vue({
        router:VueRouter,
        store:Store,
        template:'<App/>',
        components: {App}
    }).$mount('#app')

    关键代码:axios.defaults.baseURL = '/api',作用是我们每次发送的请求都会带一个/api的前缀。

    2.配置代理

    在config文件夹下的index.js文件中的proxyTable字段中,作如下处理:

    dev: {
        env: require('./dev.env'),
        port: 8090,
        autoOpenBrowser: true,
        assetsSubDirectory: 'static',
        assetsPublicPath: '/',
        proxyTable: {
          '/api': {
            target:'http://api.douban.com/v2', // 你请求的第三方接口
            changeOrigin:true, // 在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
            pathRewrite:{  // 路径重写,
              '^/api': ''  // 替换target中的请求地址,也就是说以后你在请求http://api.douban.com/v2/XXXXX这个地址的时候直接写成/api即可。
            }
          }
        },
        // CSS Sourcemaps off by default because relative paths are "buggy"
        // with this option, according to the CSS-Loader README
        // (https://github.com/webpack/css-loader#sourcemaps)
        // In our experience, they generally work as expected,
        // just be aware of this issue when enabling this option.
        cssSourceMap: false
      }

    3.在具体使用axios的地方,修改url如下即可:

    axios.get("/movie/top250").then((res) => {
                      res = res.data
                      if (res.errno === ERR_OK) {
                         this.themeList=res.data;
                      }
                    }).catch((error) => {
                      console.warn(error)
                    })

    4.重新启动项目之后,已经解决了跨域问题,结果如下:

     

    原理:

    因为我们给url加上了前缀/api,我们访问/movie/top250就当于访问了:localhost:8080/api/movie/top250(其中localhost:8080是默认的IP和端口)。

    在index.js中的proxyTable中拦截了/api,并把/api及其前面的所有替换成了target中的内容,因此实际访问Url是http://api.douban.com/v2/movie/top250。

    至此,纯前端配置代理解决axios跨域得到解决。

    方案2:后端处理跨域问题,加个过滤器即可解决,如下:

    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;
        }
         */
    }

    转自:https://blog.csdn.net/wh_xmy/article/details/87705840

  • 相关阅读:
    [转]Oracle 语法之 OVER (PARTITION BY ..) 及开窗函数
    oracle本月、上月、去年
    Oracle 物理视图刷新报错ORA-00942
    [转]Oracle trunc()函数的用法
    [转]物化视图创建 及 刷新机制修改
    [转]oracle制定定时任务(dbms_jobs)
    【转】Windows平台下的Subversion安装配置新手指南
    【转】数字签名与数字证书
    [转]SQL 常用函数及示例
    【转】视图、索引、存储过程 、触发器、游标及事务
  • 原文地址:https://www.cnblogs.com/vickylinj/p/14416616.html
Copyright © 2020-2023  润新知