对于前后端分离的项目,这里面会涉及到信息数据的交互,前端向后台系统发起请求,后台系统接收请求处理请求,将前端所需数据传递回去,因此在这涉及到的就是跨域请求,即当你的前端项目和后台项目不在同一台服务器上运行,或者在同一台服务器上不同端口运行,发送请求即是跨域请求。
在前端框架VUE中组件axios就是处理跨域请求的组件,本人也是刚刚开始接触学习,百度了很多,现将自己的心得与所学记录下来,与大家分享,文中有错误的地方,欢迎各位大佬指正。
首先先安装axios,在这里我用的cnpm,如果是npm,是同理的,将cnpm替换成npm
cnpm install axios
要实现的功能大致如下描述:
整个页面如下图所示,可根据查询条件查询出符合要求的数据,涉及的组件为el-table、axios,需要点击<查询>按钮实现axios跨域请求,将数据动态渲染到el-table中,这大概就是这次要整体实现的功能。
接下来代码剖析:
前端页面:
<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();
}
}
}
截取部分信息结果如图所示:
欢迎大家留言指正。