对于前后端分离的项目,这里面会涉及到信息数据的交互,前端向后台系统发起请求,后台系统接收请求处理请求,将前端所需数据传递回去,因此在这涉及到的就是跨域请求,即当你的前端项目和后台项目不在同一台服务器上运行,或者在同一台服务器上不同端口运行,发送请求即是跨域请求。

在前端框架VUE中组件axios就是处理跨域请求的组件,本人也是刚刚开始接触学习,百度了很多,现将自己的心得与所学记录下来,与大家分享,文中有错误的地方,欢迎各位大佬指正。

首先先安装axios,在这里我用的cnpm,如果是npm,是同理的,将cnpm替换成npm

cnpm install axios

要实现的功能大致如下描述:

整个页面如下图所示,可根据查询条件查询出符合要求的数据,涉及的组件为el-table、axios,需要点击<查询>按钮实现axios跨域请求,将数据动态渲染到el-table中,这大概就是这次要整体实现的功能。

axios 携带Cookie 跨域 axios的跨域_跨域请求


接下来代码剖析:

前端页面:

<div id="app" class="dashboard-container">

        <el-col>
          <el-form-item prop="Ucode" label-width="100px" label="用户编码:">
            <el-input v-model="Ucode" name="Ucode" class="input-style" placeholder="请输入内容" @input="change($event)" />
          </el-form-item>
          <el-form-item prop="Uname" label-width="100px" label="用户姓名:">
            <el-input v-model="Uname" name="Uname" class="input-style" placeholder="请输入内容" @input="change($event)" />
          </el-form-item>
          <el-button type="primary" icon="el-icon-search" class="button1" @click="queryUserInfo">查询</el-button>
        </el-col>

        <el-table
          :data="userData"        
          style="width: 956px;"
          border
        >
          <el-table-column type="selection" width="55" />
          <el-table-column align="center" label="序号" width="180" prop="id" />
          <el-table-column align="center" label="用户编码" width="180" prop="userCode" />
          <el-table-column align="center" label="用户姓名" width="180" prop="userName" />
          <el-table-column align="center" label="用户性别" width="180" prop="userSex" />
          <el-table-column align="center" label="用户年龄" width="180" prop="userAge" />
        </el-table>
      </div>
    </el-form>
  </div>

js代码:

<script>
new Vue({
  el:'#app',
  data:{
    Ucode:'',
    Uname:''
  }
});
</script>
<script>
//引入axios
import axios from 'axios'
export default {
  name: 'Dashboard',
  computed: {
  },
  data(){
    return{
      userData:[]
    }
  },

  methods:{
  change(e){
    this.$forceUpdate();
  },
  queryUserInfo:function(event){
      let _this = this;//这行很重要,需要绑定this,后续直接this.userData可能会取不到值
     /*
     * 问题说明:axios跨域请求,请求的参数不是传统jsp页面form表单提交那样,
     * 后台获取参数request.getParameter()的方式将获取不到axios跨域请求的
     * 参数,所以需如下一样进行封装,如下的方式有多种,可自行百度选择
     */ 
      var param = new URLSearchParams();
      param.append('usercode',this.Ucode);
      param.append('username',this.Uname);
      //这里的ip取大家运行项目所在环境的IP地址及端口号
      axios.post('http://ip:8080/Epos/VueElementBackService/callBackNotify',param)
        .then(function(response){
          console.log(response.data);
          /*
          * 问题说明:在这里存在一个后台返回的json字符串要不要转换的问题。
          * 1、如果后台用的JSONObject对象,将数据封装转换成json字符串返回给
          * 是不用转换的,这里直接接收就行,但要注意的是这里返回的字符串是
          * 这种类型:{"id":1,"userCode":"001","userSex":"男","userName":"超级管理员(总公司管理员)","userAge":"20"}
          * 在接收的时候需要外套一层中括号:[],如:_this.userData = [response.data];
          * 这样组件el-table就会自动填充数据,无需遍历取填充。
          * 2、如果后台用的是tJSONArray对象,直接接收就行了,如:_this.userData = response.data;
          * 如大家所见,两种方式都无需转换。在这里只针对这两种情况,如果大家
          * 用其他的方式,请根据实际情况处理
          */
          _this.userData = response.data;
        }).catch(function(error){
          console.log(error);
        });
    }
  }

}
</script>
//这里是关于两个查询条件输入框输入值
function newFunction() {
    change(e);
    {
      this.$forceUpdate();
    }
  }

接下来就是java代码:api接口

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * 程序功能:api接口(基于RESTful)
 */
@Controller
@RequestMapping("/VueElementBackService")
public class VueElementBackService {
		

	 @RequestMapping(value = "/callBackNotify",method = RequestMethod.POST, produces = "text/json;charset=UTF-8")
	 public void getResultOfVueElement(HttpServletRequest request, HttpServletResponse response){
		 try{
			 System.out.println("=============进入VUE前端回调接口==========");
			
			 String usercode = request.getParameter("usercode");
			 String username = request.getParameter("username");
			 
			 String tSql = "SELECT t.usercode,t.username,'20' userage,'男' usersex FROM lduser t WHERE 1=1  ";
	        
	         if(usercode != "" && usercode != null && !"undefined".equals(usercode)){
	        	 tSql = tSql + " AND t.usercode = '"+usercode+"'";
	         }
	         if(username != "" && username != null&& !"undefined".equals(username)){
	        	 tSql = tSql + " AND t.username='"+username+"'";
	         }
	         //封装了执行sql语句,获取结果集的方法,这里不方便贴出,大家根据自己所使用持久层框架进行访问数据库
	         ExeSQL tExeSQL = new ExeSQL();
	         //封装的结果集
	         SSRS tSSRS = new SSRS();
	         tSSRS = tExeSQL.execSQL(tSql);
	         
	         String userCode = "";
	         String userName = "";
	         String userAge = "";
	         String userSex = "";
	         JSONObject tJSONObject = new JSONObject();
	         JSONArray tJSONArray = new JSONArray();
	         if(tSSRS.MaxRow > 0 ){
	        	 for (int i = 1; i <= tSSRS.MaxRow; i++) {
	        		 userCode =  tSSRS.GetText(i, 1);
	        		 userName =  tSSRS.GetText(i, 2);
	        		 String userNameUtf = new String(getUTF8BytesFromGBKString(userName),"UTF-8");
	        		 userAge =  tSSRS.GetText(i, 3);
	        		 userSex =  tSSRS.GetText(i, 4);
	        		 String userSexUtf = new String(getUTF8BytesFromGBKString(userSex),"UTF-8");
	        		 tJSONObject.put("id", i);
	        		 tJSONObject.put("userCode", userCode);
	        		 tJSONObject.put("userName", userNameUtf);
	        		 tJSONObject.put("userAge", userAge);
	        		 tJSONObject.put("userSex", userSexUtf);
	        		 
	        		 
	        		 tJSONArray.add(tJSONObject);
	        		 tJSONObject.clear();
	        		 
				 }
	        	 
	         }
	         /* 这里涉及到跨域请求存在的问题,在响应头设置这些参数,
             * 前端才能正确获取到我们传回的json字符串,否则前端会报错,
             * 有很多方式,我选择一个最懒最笨的方式,在实际项目中还是
             * 不要采用这种方式,可以配置在拦截器里或添加标签等。
             */             
	         response.setHeader("Access-Control-Allow-Origin", "*"); //解决跨域访问报错 
	         response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE"); 
	         response.setHeader("Access-Control-Max-Age", "3600"); //设置过期时间 
	         response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization"); 
	         response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支持HTTP 1.1. 
	         response.setHeader("Pragma", "no-cache"); // 支持HTTP 1.0. response.setHeader("Expires", "0"); 
	        
	         String jsonStr = tJSONArray.toString();
	         tJSONArray.clear();
	       
	         System.out.println("返回json字符串:"+jsonStr);
	         response.getWriter().write(jsonStr);
        
		 }catch(Exception e){
			 e.printStackTrace();
		 }
		 
		 
	 }
	
}

截取部分信息结果如图所示:

axios 携带Cookie 跨域 axios的跨域_vue_02


欢迎大家留言指正。