1.vue-resource发送get,post,jsonp请求
Vue 要实现异步加载需要使用到 vue-resource 库。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-resource发送get,post,jsonp请求</title>
</head>
<body>
<div id="app">
<input type="button" value="get请求" @click="getInfo">
<input type="button" value="post请求" @click="postInfo">
<input type="button" value="jsonp请求" @click="jsonpInfo">
</div>
<script type="text/javascript" src="js/vue.js" charset="UTF-8"></script>
<!--先导入vue.js,再引入vue-resource-->
<script type="text/javascript" src="js/vue-resource.js" charset="UTF-8"></script>
<script type="text/javascript" charset="UTF-8">
var vm=new Vue({
el:'#app',
data:{
},
methods:{
getInfo(){
//发送get请求
var url="http://vue.studyit.io/api/getlunbo";
this.$http.get(url,{}).then(function (result) {
console.log(result);
})
},
postInfo(){
//注意:post请求需要提交表单类型的参数(option选项列表中添加'emulateJSON:true')
var url="http://vue.studyit.io/api/getlunbo";
this.$http.post(url,{},{emulateJSON:true}).then(function (result) {
console.log(result);
})
},
jsonpInfo(){
var url="http://vue.studyit.io/api/getlunbo";
this.$http.jsonp(url,{},{}).then(function (result) {
console.log(result);
})
}
}
})
</script>
</body>
</html>
2.jsonp跨域请求
2.1.原理
①.由于浏览器的安全性限制,不允许ajax访问协议不同,域名不同,端口号不同的数据接口,浏览器认为这种访问不安全;
②. 可以通过动态创建script标签的形式,把script标签的src属性指向数据接口的地址,因为script标签不存在跨域限制,这样的数据获取方式被称作为jsonp;
2.2.实现过程
1>.在客户端事先定义一个回调函(预定义对数据的操作),用于服务器端回调
<script>
function callbackFunction(data){
//to do something
}
</script>
2>.再把这个回调方法的名称(参数不要),通过URL传参的形式提交到服务器端的数据接口
<script src=”http://xxx/xxx?callback=callbackFunction”></script>
3>.服务器端数据接口对应的方法中要组织好将要发送给客户端(/回调函数要请求)的数据,再拿着客户端传递过来的回调函数的名称,拼接出一个调用这个回调函数的字符串,发送到客户端去解析执行
4>.客户端拿到服务器端返回的(包含回调函数名称)字符串之后,把他当作script脚本去解析执行,这样就可以拿到jsonp的数据
3.案例:品牌列表从数据库获取列表
3.1.基本实现
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<title>品牌列表</title>
<link href="static/boostrap/css/bootstrap.min.css" rel="stylesheet">
<style type="text/css">
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id=app>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">
品牌列表
</h3>
</div>
<div class="panel-body">
<table class="table table-hover table-responsive table-bordered table-striped" style="margin-bottom: 0px;">
<div class="form-inline">
<div class="col-md-6 col-lg-6 col-sm-6">
<label>
NAME:
<input type="text" class="form-control" v-model="name" @keyup.enter="add()">
</label>
<label>
<button class="btn btn-primary" @click="add()">添加</button>
</label>
</div>
<div class="col-md-6 col-lg-6 col-sm-6 text-right">
<label>
<input type="text" class="form-control" v-model="keywords">
<button type="button" class="btn btn-primary" @click="search()">搜索</button>
</label>
</div>
</div>
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in list" :key="item.id">
<td v-text="item.id"></td>
<td v-text="item.name"></td>
<td v-text="item.cTime"></td>
<td>
<a @click="del(item.id)">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript" src="static/js/vue.js" charset="UTF-8"></script>
<script type="text/javascript" src="static/js/vue-resource.js"></script>
<script type="text/javascript" charset="UTF-8">
//全局过滤器,格式化日期
Vue.filter('dataFormat', function (data, pattern) {
//根据给定的时间字符串,得到一个特定的时间
var dt = new Date(data);
var y = dt.getFullYear();
var m = dt.getMonth() + 1;
var d = dt.getDate();
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`;
} else {
var hh = dt.getHours();
var mm = dt.getMinutes();
var ss = dt.getSeconds();
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
});
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
keywords: '',
list: {}
},
created(){
//第二个生命周期函数,表示data和methods内容都已经被初始化好了
//提前发送请求,初始化数据,增强用户体验
this.search(this.keywords);
},
methods: {
del(id) {
this.$http.delete("brand/delete/"+id,{},{}).then(result=>{
var body=result.body;
if (body.code==200){
//删除页面上的元素
//根据id找到list对应的对象,删除他
this.list.some((item, i) => {
if (item.id == id) {
//删除list中对应的元素
this.list.splice(i, 1);
//终止循环
return true;
}
})
}else{
alert("删除失败!");
}
},result=>{
console.log("请求失败!");
})
},
add() {
//获取用户输入的内容
var name = this.name;
if (name==null || name==''){
alert("品牌名称不能为空!");
return;
}
//发送ajax请求
this.$http.post("brand/add",{
name:name
},{emulateJSON:true}).then(result=>{
var body=result.body;
if (body.code==200){
//属性产品列表
this.search();
} else{
alert("添加失败!")
}
},result=>{
console.log("请求失败!");
});
//清空输入的内容
this.name = "";
},
search() {
var url="";
if (this.keywords==null || this.keywords==''){
url="brand/list"
}else {
url="brand/search/"+this.keywords;
}
//发送get请求
this.$http.get(url).then(result => {
var body = result.body;
if (body.code == 200) {
//将数据库中查询的数据放入到list中
this.list = body.data;
} else {
alert("查询失败!");
}
}, result => {
console.log("请求失败!");
})
}
}
})
</script>
</body>
</html>
3.2.全局配置数据接口的根域名
<script type="text/javascript" src="static/js/vue.js" charset="UTF-8"></script>
<script type="text/javascript" src="static/js/vue-resource.js"></script>
<script type="text/javascript" charset="UTF-8">
//使用全局配置设置默认值(vue-resource)
//服务器请求的根路径,之后的url字符串前面不能再加"/"了!
Vue.http.options.root="http://localhost:8080/";
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
keywords: '',
list: {}
},
created(){
//第二个生命周期函数,表示data和methods内容都已经被初始化好了
//提前发送请求,初始化数据,增强用户体验
this.search(this.keywords);
},
methods: {
del(id) {
this.$http.delete("brand/delete/"+id,{},{}).then(result=>{
var body=result.body;
if (body.code==200){
//删除页面上的元素
//根据id找到list对应的对象,删除他
this.list.some((item, i) => {
if (item.id == id) {
//删除list中对应的元素
this.list.splice(i, 1);
//终止循环
return true;
}
})
}else{
alert("删除失败!");
}
},result=>{
console.log("请求失败!");
})
},
add() {
//获取用户输入的内容
var name = this.name;
if (name==null || name==''){
alert("品牌名称不能为空!");
return;
}
//发送ajax请求
this.$http.post("brand/add",{
name:name
},{emulateJSON:true}).then(result=>{
var body=result.body;
if (body.code==200){
//属性产品列表
this.search();
} else{
alert("添加失败!")
}
},result=>{
console.log("请求失败!");
});
//清空输入的内容
this.name = "";
},
search() {
var url="";
if (this.keywords==null || this.keywords==''){
url="brand/list"
}else {
url="brand/search/"+this.keywords;
}
//发送get请求
this.$http.get(url).then(result => {
var body = result.body;
if (body.code == 200) {
//将数据库中查询的数据放入到list中
this.list = body.data;
} else {
alert("查询失败!");
}
}, result => {
console.log("请求失败!");
})
}
}
})
</script>
3.3.全局配置emulateJson选项
<script type="text/javascript" src="static/js/vue.js" charset="UTF-8"></script>
<script type="text/javascript" src="static/js/vue-resource.js"></script>
<script type="text/javascript" charset="UTF-8">
//使用全局配置设置默认值(vue-resource)
//服务器请求的根路径,之后的url字符串前面不能再加"/"了!
Vue.http.options.root="http://localhost:8080/";
//当发送post请求的时候,就不要在post请求中添加该属性了
Vue.http.options.emulateJSON=true;
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
keywords: '',
list: {}
},
created(){
//第二个生命周期函数,表示data和methods内容都已经被初始化好了
//提前发送请求,初始化数据,增强用户体验
this.search(this.keywords);
},
methods: {
del(id) {
this.$http.delete("brand/delete/"+id,{},{}).then(result=>{
var body=result.body;
if (body.code==200){
//删除页面上的元素
//根据id找到list对应的对象,删除他
this.list.some((item, i) => {
if (item.id == id) {
//删除list中对应的元素
this.list.splice(i, 1);
//终止循环
return true;
}
})
}else{
alert("删除失败!");
}
},result=>{
console.log("请求失败!");
})
},
add() {
//获取用户输入的内容
var name = this.name;
if (name==null || name==''){
alert("品牌名称不能为空!");
return;
}
//发送ajax请求
this.$http.post("brand/add",{
name:name
},{}).then(result=>{
var body=result.body;
if (body.code==200){
//属性产品列表
this.search();
} else{
alert("添加失败!")
}
},result=>{
console.log("请求失败!");
});
//清空输入的内容
this.name = "";
},
search() {
var url="";
if (this.keywords==null || this.keywords==''){
url="brand/list"
}else {
url="brand/search/"+this.keywords;
}
//发送get请求
this.$http.get(url).then(result => {
var body = result.body;
if (body.code == 200) {
//将数据库中查询的数据放入到list中
this.list = body.data;
} else {
alert("查询失败!");
}
}, result => {
console.log("请求失败!");
})
}
}
})
</script>