Loading

Vue3 cli+ axios + servlet跨域问题解决,简单get post 请求

Vue3 cli + axios + servlet跨域问题解决,简单get post 请求

问题

最近在vue-cli使用vue3测试版进行构建项目时视图使用axios进行异步操作,但get和post方式都无法正常完成,提示

Access to XMLHttpRequest at 'http:/localhost:8080/FinalHome_war_exploded2/AreaInitServlet' from origin 'http://localhost:8989' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
笔者这里使用端口8989作为vue-cli热更新的端口,使用默认的8080作为tomcat的端口 查阅了很多博文和资料,最终设置代理解决。

配置代理

首先在Vue主程序根目录下新建一个文件vue.config.js作为配置主文件,写入:

module.exports = {
    devServer: {
        port:8989,
        proxy: {
            '/api': {
                target: 'http://localhost:8080/FinalHome_war_exploded2/',
                // 允许跨域
                changeOrigin: true,
                ws: true,
                pathRewrite: {
                    '^/api': ''
                      //  '^/api': '/' 效果完全一样
                }
            }
        }
    }
}

这里修改了web server的端口号

当用户请求的url中含有/api串时,会被自动替换为target对应的网址(此处为http://localhost:8080/FinalHome_war_exploded2/)

如果将pathRewrite改为'^/api': '/api则会自动替换为XXX/api(此处为http://localhost:8080/FinalHome_war_exploded2/api)

此外,还要在根目录的main.js(vue程序默认入口,可以自定义)下添加

import Axios from 'axios';
let ROOT;
if (process.env.NODE_ENV === 'development') {
    ROOT = "/api";//开发环境下的代理地址,解决本地跨域
} else {
    ROOT = 'http://XX.XX.XX.XX';    //生产环境下的地址
}
Axios.defaults.baseURL = ROOT;
//使得每次请求都会带一个/api前缀,然后被自动替换为target中的网址

这段代码放在createApp命令之前

Servlet代码修改(get+post)

由于是老项目,使用的还是javeEE 5.0标准(6+使用注解)
src/main/java/XXX.XXX.XXX/XXX/包下新建java文件,继承httpServlet类

package zcib.yuri.control;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class VueTestAxiosServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("Post:" + username);
        System.out.println("Post:" + password);
        PrintWriter out = response.getWriter();
        out.print("success"); //输出到IO流
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.print("I Love JavaScript"); //输出到IO流

    }
}

在web.xml中注册

  <servlet>
    <servlet-name>VueTestAxiosServlet</servlet-name>
    <servlet-class>zcib.yuri.control.VueTestAxiosServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>VueTestAxiosServlet</servlet-name>
    <url-pattern>/VueTestAxiosServlet</url-pattern>
  </servlet-mapping>

Axios

这里将SmartHome.vueVUE实例以main.js为中介挂载到index.html#app节点上:
SmartHome.vue

....
<script>/
import axios from "axios";
import qs from 'qs'
export default {
  name: "SmartHome",
  data() {
    return {
      gotData: {}
    }
  },
  mounted() {
    //get请求
     axios.get('/VueTestAxiosServlet').then((res) => {
       console.log(res);
       console.log(res.data)
     }).catch((err) => {
       console.log('请求失败' + err);
     })
    }
}
</script>
...

如果以get方式从后端读取数据,运行vue程序,打开浏览器控制台可以看到回传的数据

如果希望传回Map、ListMap或者Array等集合类型数据,可以结合使用fastjson等工具转化为json再传输,这里不再赘述

如果以post方式向后端传递数据:

请注意axios默认向目标传递的格式是json,所以我们还需要将它转化为formData格式或者将其序列化,本次使用后一种方法
axios自带一个插件qs,直接使用es6模块管理导入使用:
SmartHome.vue

...
<script>
import axios from "axios";
import qs from 'qs'
export default {
  name: "SmartHome",
  data() {
    return {
      gotData: {}
    }
  },
  mounted() {
    //在vue组件渲染完成时执行操作
    //post请求
    let userData = {
      username:'Tony Tony',
      password:'12312313'
    }
    let data = qs.stringify(userData);
    console.log('zhuanhuan' +data);
    axios.post('/VueTestAxiosServlet',data).then((res) => {
      console.log(res);
      console.log(res.data);
    }).catch((err) => {
          console.log(err);
        }
    )
  }
}
...
</script>

运行这个vue程序,打开控制台,可以看到拼接成功的序列化串

且后端已经接收到了username和password内容

posted @ 2021-02-02 20:38  Maji-May  阅读(1059)  评论(0编辑  收藏  举报