vue中使用Ajax(axios)、vue函数中this指向问题
Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中。
axios中文文档库:http://www.axios-js.com/zh-cn/docs/
git地址:https://github.com/axios/axios
1.Axios简单使用
1.axios发送简单的get请求
后台:
@RequestMapping("/index")
@ResponseBody
public Map index(HttpServletRequest request, HttpServletResponse response, @RequestParam Map condition) {
System.out.println(condition);
// 允许ajax跨域请求
response.setHeader("Access-Control-Allow-Origin", "*");
return condition;
}
前台:
<!DOCTYPE html>
<html> <head>
<meta charset="utf-8" />
<title></title>
<script src="js/axios.min.js" type="text/javascript" charset="utf-8"></script>
</head> <body>
<script>
// 为给定 ID 的 user 创建请求
axios.get('http://localhost:8088/weixin/test/index.html?name=zs')
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
</script>
</body> </html>
结果:
上面的请求还可以:
<script>
// 上面的请求也可以这样做
axios.get('http://localhost:8088/weixin/test/index.html', {
params: {
name: 'zs2'
}
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
</script>
2.发送POST请求
后台需要过滤器中允许跨域请求:
package cn.qlq.filter; import java.io.IOException; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse; /**
* 允许跨域请求
*/
@WebFilter(filterName = "corsFilter", urlPatterns = "/*")
public class CorsFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println(1);
HttpServletResponse response2 = (HttpServletResponse) response;
response2.setHeader("Access-Control-Allow-Origin", "*"); // 解决跨域访问报错
response2.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response2.setHeader("Access-Control-Max-Age", "3600"); // 设置过期时间
response2.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization");
response2.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支持HTTP
// 1.1.
response2.setHeader("Pragma", "no-cache"); // 支持HTTP 1.0.
// response.setHeader("Expires",
// "0"); chain.doFilter(request, response);
} @Override
public void destroy() { } @Override
public void init(FilterConfig arg0) throws ServletException { } }
Controller代码:
@RequestMapping("/index")
@ResponseBody
public Map index(HttpServletRequest request, HttpServletResponse response, @RequestBody Map condition) {
System.out.println(condition); return condition;
}
前台代码:
<script>
axios.post('http://localhost:8088/weixin/test/index.html', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
</script>
结果:
post的请求头Content-Type是application/json,发送JSON数据请求
补充:关于axios中发送同步请求
有时候必须使用同步请求,比如请求回数据之后做其他处理。ajax请求的话使用async:false即可。在axios中的话没有提供参数,需要借助 async 函数和 await关键字。async 是 ES7 才有的。
例如:axios默认异步请求
function test() {
console.log(1); axios.post('http://localhost:8088/weixin/test/index.html', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
}); console.log(2);
} test();
结果:
发送同步请求:
async function test() {
console.log(1); var response = await axios.post('http://localhost:8088/weixin/test/index.html', {
firstName: 'Fred',
lastName: 'Flintstone'
}); console.log(response); console.log(2);
} test();
结果:
3.请求配置
{
// `url` 是用于请求的服务器 URL
url: '/user', // `method` 是创建请求时使用的方法
method: 'get', // default // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/', // `transformRequest` 允许在向服务器发送前,修改请求数据
// 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
transformRequest: [function (data, headers) {
// 对 data 进行任意转换处理
return data;
}], // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对 data 进行任意转换处理
return data;
}], // `headers` 是即将被发送的自定义请求头
headers: {'X-Requested-With': 'XMLHttpRequest'}, // `params` 是即将与请求一起发送的 URL 参数
// 必须是一个无格式对象(plain object)或 URLSearchParams 对象
params: {
ID: 12345
}, // `paramsSerializer` 是一个负责 `params` 序列化的函数
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
}, // `data` 是作为请求主体被发送的数据
// 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
// 在没有设置 `transformRequest` 时,必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属:FormData, File, Blob
// - Node 专属: Stream
data: {
firstName: 'Fred'
}, // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
// 如果请求话费了超过 `timeout` 的时间,请求将被中断
timeout: 1000, // `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // default // `adapter` 允许自定义处理请求,以使测试更轻松
// 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
adapter: function (config) {
/* ... */
}, // `auth` 表示应该使用 HTTP 基础验证,并提供凭据
// 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头
auth: {
username: 'janedoe',
password: 's00pers3cret'
}, // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json', // default // `responseEncoding` indicates encoding to use for decoding responses
// Note: Ignored for `responseType` of 'stream' or client-side requests
responseEncoding: 'utf8', // default // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
xsrfCookieName: 'XSRF-TOKEN', // default // `xsrfHeaderName` is the name of the http header that carries the xsrf token value
xsrfHeaderName: 'X-XSRF-TOKEN', // default // `onUploadProgress` 允许为上传处理进度事件
onUploadProgress: function (progressEvent) {
// Do whatever you want with the native progress event
}, // `onDownloadProgress` 允许为下载处理进度事件
onDownloadProgress: function (progressEvent) {
// 对原生进度事件的处理
}, // `maxContentLength` 定义允许的响应内容的最大尺寸
maxContentLength: 2000, // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // default
}, // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
// 如果设置为0,将不会 follow 任何重定向
maxRedirects: 5, // default // `socketPath` defines a UNIX Socket to be used in node.js.
// e.g. '/var/run/docker.sock' to send requests to the docker daemon.
// Only either `socketPath` or `proxy` can be specified.
// If both are specified, `socketPath` is used.
socketPath: null, // default // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
// `keepAlive` 默认没有启用
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }), // 'proxy' 定义代理服务器的主机名称和端口
// `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
// 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
proxy: {
host: '127.0.0.1',
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l'
}
}, // `cancelToken` 指定用于取消请求的 cancel token
// (查看后面的 Cancellation 这节了解更多)
cancelToken: new CancelToken(function (cancel) {
})
}
4.响应结构
{
// `data` 由服务器提供的响应
data: {}, // `status` 来自服务器响应的 HTTP 状态码
status: 200, // `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK', // `headers` 服务器响应的头
headers: {}, // `config` 是为请求提供的配置信息
config: {},
// 'request'
// `request` is the request that generated this response
// It is the last ClientRequest instance in node.js (in redirects)
// and an XMLHttpRequest instance the browser
request: {}
}
补充:关于axios拦截器的使用
有时候希望发送请求处理之前和之后做一些处理。比如说每个请求携带token参数,接收消息之后根据回传的结果验证是否正确,不正确统一处理。
前端代码:
// 添加请求拦截器
axios.interceptors.request.use(function(config) {
// 模拟处理前增加token
console.log("处理前 ");
config.data.token = "123456"; return config;
}, function(error) {
// 对请求错误做些什么
return Promise.reject(error);
}); // 添加响应拦截器
axios.interceptors.response.use(function(response) {
// 对响应数据做点什么
console.log("处理后"); if(response.data.success) {
// 如果是成功返回信息之后提取出来返回以供后面的调用链使用
return response.data.data;
} else {
// 如果返回false记录一下返回Promise 对象。不会执行当前promise.
console.log(response.data.msg);
return new Promise(function(resolve, reject) {
// resolve('success1');
// reject('error');
});
}
}, function(error) {
// 对响应错误做点什么
return Promise.reject(error);
}); function test() {
axios.post('http://localhost:8088/test/test.html', {
firstName: 'Fred',
lastName: 'Flintstone'
}).then(function(resData) {
// 这里处理返回的data
console.log(resData);
});
} test();
后端返回的JSON工具类:
package cn.qs.utils; import java.io.Serializable; public class JSONResultUtil<T> implements Serializable { private static final long serialVersionUID = 3637122497350396679L; private boolean success;
private T data;
private String msg; public boolean isSuccess() {
return success;
} public void setSuccess(boolean success) {
this.success = success;
} public T getData() {
return data;
} public void setData(T data) {
this.data = data;
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} public JSONResultUtil(boolean success) {
this.success = success;
} public JSONResultUtil(boolean success, String msg) {
super();
this.success = success;
this.msg = msg;
} public JSONResultUtil(boolean success, T data, String msg) {
super();
this.success = success;
this.data = data;
this.msg = msg;
} /**
* 返回正确结果不带数据
*
* @return
*/
public static JSONResultUtil ok() {
return new JSONResultUtil(true);
} /**
* 返回错误的结果带错误信息
*
* @param msg
* @return
*/
public static JSONResultUtil error(String msg) {
return new JSONResultUtil(false, msg);
}
}
Controller返回正确:
@PostMapping("/test")
public JSONResultUtil<String> Test(@RequestBody String condition) {
System.out.println(condition); return new JSONResultUtil<String>(true, condition, "ok");
}
结果:
Controller返回false:
@PostMapping("/test")
public JSONResultUtil<String> Test(@RequestBody String condition) {
System.out.println(condition); return new JSONResultUtil<String>(false, null, "error");
}
结果:
2.vue中使用axios
1. 简单使用
后端代码:
@RequestMapping("/index")
@ResponseBody
public Map index(HttpServletRequest request, HttpServletResponse response, @RequestBody Map condition) {
condition.put("name", "zs");
condition.put("age", 25);
return condition;
}
前台:(请求后台的JSON数据,并且将得到的数据直接赋值给自己的data属性,自己的data原来为null)
<!DOCTYPE html>
<html> <head>
<meta charset="utf-8" />
<title></title>
<script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/axios.min.js" type="text/javascript" charset="utf-8"></script>
</head> <body>
<div id="app">
<h1>{{ data.name }} - {{ data.age }}</h1>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
data: null
},
mounted() {
axios
.post('http://localhost:8088/weixin/test/index.html', {
'test': 123
})
.then(response => (this.data = response.data))
.catch(function(error) { // 请求失败处理
console.log(error);
});
}
})
</script>
</body> </html>
结果:
2. 请求图片流
1.方法一:
第一种方法就是向后台请求一个图片URL,然后改变image的src属性实现,其静态实例如下:
<div id="vue_det">
<img :src="src" />
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue_det',
data: {
src: "http://localhost:8088/static/images/1.png",
}
})
</script>
2.方法2:
使用JS请求数据流。
<div id="vue_det">
<img :src="imgUrl" class="logoImg">
</div>
<script type="text/javascript">
var vm = new Vue({
el: '#vue_det',
data: {
imgUrl: '123'
},
mounted: function() {
var url = 'http://localhost:8088/static/images/1.png';
axios.get(url, {
responseType: 'arraybuffer'
}).then(function(data) {
vm.imgUrl = 'data:image/png;base64,' + btoa(new Uint8Array(data.data).reduce((data, byte) => data + String.fromCharCode(byte), ''))
console.log(this.imgUrl)
}).catch(function(err) {
console.error(err)
});
}
})
</script>
注意:
(1)vue组件或者实例中,不管是生命周期钩子函数created还是自定义函数plus,他们中的this都是指当前vue实例。
(2)回调函数中,如果是普通函数,this指向window对象,如果是 ES6的 =>箭头函数,this指向当前实例。所以建议一般情况下用箭头函数指向当前实例。
<script type="text/javascript">
var vm = new Vue({
el: '#vue_det',
data: {
imgUrl: '123'
},
mounted: function() {
console.log(this);
var url = 'http://localhost:8088/static/images/1.png';
axios.get(url, {
responseType: 'arraybuffer'
}).then(function(data) {
console.log(this);
vm.imgUrl = 'data:image/png;base64,' + btoa(new Uint8Array(data.data).reduce((data, byte) => data + String.fromCharCode(byte), ''))
}).catch(function(err) {
console.error(err)
});
}
})
</script>
结果:
<script type="text/javascript">
var vm = new Vue({
el: '#vue_det',
data: {
imgUrl: '123'
},
mounted: function() {
console.log(this);
var url = 'http://localhost:8088/static/images/1.png';
axios.get(url, {
responseType: 'arraybuffer'
}).then(data => {
console.log(this);
this.imgUrl = 'data:image/png;base64,' + btoa(new Uint8Array(data.data).reduce((data, byte) => data + String.fromCharCode(byte), ''))
}).catch(function(err) {
console.error(err)
});
}
})
</script>
结果:
补充:如果想在函数普通回调函数中用当前vue实例对象,可以在外面提前将this付给一个变量,例如:
async onChangeKindergarten(value) {
// 将_this指向当前vm对象
const _this = this;
var confirmContent = '您确定要选择 ' + value + ' 吗?您只有一次修改的机会!';
this.$vux.confirm.show({
title: '',
content: confirmContent,
onConfirm() {
axios.post('/user/updateLoginUser.html', {
remark1: value
}); _this.remark1 = value;
_this.$vux.toast.text('修改成功');
},
onCancel() {
_this.remark1 = '';
}
})
}
vue中使用Ajax(axios)、vue函数中this指向问题的更多相关文章
- vue中的ajax - axios
vue中的ajax - axios axios - 简书 使用 axios 实现 ajax 方案 VUE 更好的 ajax 上传处理 axios.js vue.js 自2.0版本已经不对 vue-re ...
- js闭包中的this(匿名函数中的this指向的是windows)
js闭包中的this(匿名函数中的this指向的是windows) 一.总结 1.普通函数中的this指向的是对象,匿名函数中的this指向的是windows,和全局变量一样 2.让匿名函数中的thi ...
- laravel 中使用ajax和vue总结
最近写一个项目是基于laravel框架的,这个框架传言是为艺术而创作的优雅框架,简洁分明的风格,很吸引我,所以最近研究比较多.本次就是基于该框架然后将Vue插件加入实现一定的功能,vue插件本身强大, ...
- js中的this和箭头函数中的this
一.ES6 允许使用"箭头"(=>)定义函数. // var f = v => v;// 上面的箭头函数等同于: // var f = function(v) {// ...
- Python中random模块在主函数中设置随机种子是否对于调用的函数中的随机值产生影响?
一个问题,加入我有一个工程文件,在main函数里面调用random模块,设置随机种子,主函数中的随机种子的设置是否会影响主函数所调用的函数中的随机值? 实际上这个问题非常重要,比如你在跑网络的时候,初 ...
- 箭头函数中的this和普通函数中的this对比
ES6中新增了箭头函数这种语法,箭头函数以其简洁性和方便获取this的特性.下面来总结一下他们之间的区别: 普通函数下的this: 在普通函数中的this总是代表它的直接调用者,在默认情况下,this ...
- IT兄弟连 JavaWeb教程 jQuery中其他AJAX支持的函数
● $.get()函数 $.get(url,data,function,dataType);参数说明如下: url:请求地址 data:请求参数 dataType:服务器返回的数据类型 functi ...
- C语言中指针变量如何向函数中传递
指针变量存储的是地址,所以在函数调用的时候我们能否将指针变量传递给函数?如果不知道结果,那我们可以直接问电脑,输入如下一段代码. void GetMemory(char *p) { p = (char ...
- 【spring 后台跳转前台】使用ajax访问的后台,后台正常执行,返回数据,但是不能进入前台的ajax回调函数中
问题: 使用ajax访问的后台,后台正常执行,并且正常返回数据,但是不能进入前台的ajax回调函数中 问题展示: 问题解决: 最后发现是因为后台的方法并未加注解:@ResponseBody,导致方法 ...
随机推荐
- 数据库——SQL-SERVER练习(1)连接与子查询
一.实验准备 1.复制实验要求文件及“CREATE-TABLES.SQL”文件, 粘贴到本地机桌面. 2.启动SQL-SERVER服务. 3. 运行查询分析器, 点击菜单<文件>/< ...
- 第2个word发布的博客
//接收的为空时,则表示客户端下线,跳出循环 if (r == 0) { break; }; string str = Encoding.UTF8.GetString(buffer, 0, r); ...
- 自从用python写了个自动弹幕脚本后,各大主播都来找我,净赚十万!
大家好,今天又给大家带来了Python爬虫的分享,今天我们继续上次的问题,继续来研究一下虎牙平台的爬虫. 起因 写完上次的代码,我冒出有一个很有趣的想法,就是,我们可以使用selenium来完成虎牙自 ...
- 漫谈golang设计模式 工厂模式
工厂模式 意义:创建过程交给专门的工厂子类去完成.定义一个抽象的工厂类,再定义具体的工厂类来生成子类等,它们实现在抽象按钮工厂类中定义的方法.这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引 ...
- /cygdrive/c/MinGW/bin/autoconf-2.68: line 501: /mingw/bin/autom4te-2.68: No such file or directory
出现如下错误 编译openssh的时候 # autoconf /cygdrive/c/MinGW/bin/autoconf-2.68: line 501: /mingw/bin/autom4te-2. ...
- iOS10 新特性一
链接:http://www.jianshu.com/p/0cc7aad638d9 1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是 ...
- 微信小程序踩坑日记3——上传照片至服务器
0. 引言 主要解决将小程序端获取的图片保存在服务器上.亲测可用的服务端脚本. 1. 获取照片 通过wx.chooseImage()方法,获取到图片,使用wx.uploadFile()上传图片. wx ...
- 【JavaWeb】实现二级联动菜单
实现效果 频道信息 package demo; public class Channel { private String code; //频道编码 private String name; //频道 ...
- [视频教程] ubuntu系统下安装最新版PHP7.3.X环境
视频地址: https://www.bilibili.com/video/av69088870/ 笔记: 先安装一下这个命令 add-apt-repositoryapt-get install sof ...
- 微软Cloud+AI本地化社区更新
有关微软Cloud+AI本地化方面的介绍请参见我之前的文章:<微软Cloud+AI本地化社区贡献指南>,本文将公布该社区最新的活动变更事宜. MLCP改进 我们想借此机会向您介绍我们在社区 ...