在完成一个小demo时,需要将图片进行异步刷新,一开始就想到了使用ajax来完成,部分代码如下
html:
<label for="signupName" width="64px">修改头像</label>
<input id="alterHead" type="file" accept="image/png,image/gif,image/jpeg"style="display:inline-block" class="form-control">
<button id="alterHeadButton" type="button" class="btn btn-primary">确认修改</button>
jquery:
$("#alterHeadButton").click(function(event) {
if($("#alterHead").val() != undefined){
var data = $("#alterHead").val();
$.ajax({
url: '/user/alterHead',
type: 'post',
datatype:'json',
data: {head:data}
})
.done(function() {
console.log("success");
})
nodejs后台部分显示:
var headPictrue = req.body.head;
var show = "我的上面是要查看的数据";
console.log(headPictrue);
console.log(typeof headPictrue);
console.log(show);
console.log(typeof show);
而使用这个这种最标准的ajax编写时结果却是错误的
一开始十分不解便查找了相关资料,原因大致如下:
传统的方法是form表单提交,委托浏览器读取文件然后发送请求。而浏览器本身是不具备对该文件进行操作的,也没有读取磁盘的权限。而普通的ajax只能获取页面dom相关的数据。所以才会出现.val()传到后台的数据只是一个路径不完整的的字符串。
后来查看了相关文档,ajax中可以使用formdata进行数据传递,代码如下:
html:
<label for="signupName" width="64px">修改头像</label>
<input id="alterHead" type="file" accept="image/png,image/gif,image/jpeg"style="display:inline-block" class="form-control">
<button id="alterHeadButton" type="button" class="btn btn-primary">确认修改</button>
jquery:
$(function(){
$("#alterHeadButton").click(function(event) {
if($("#alterHead").val() != undefined){//判断input是否有值
var formData = new FormData();
formData.append('formData', $('#alterHead')[0].files[0]);//获取input上的第一个上传文件
$.ajax({
url: '/user/alterHead',
type: 'post',
cache: false,//上传文件不需要缓存。
data: formData,
processData: false,//data值是FormData对象,不需要对数据做处理。
contentType: false//是FormData对象,且已经声明了属性enctype="multipart/form-data",所以这里设置为false。
})
.done(function() {
console.log("success");
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
});
}
});
})
nodejs:
var headPictrue = req.files.formData;
//获取文件中的数据,,必须注意的是必须添加了connect-multiparty,来对formdata进行处理
var show = "我的上面是要查看的数据";
console.log(headPictrue);
console.log(typeof headPictrue);
console.log(show);
console.log(typeof show);
结果:
正确获得了数据,不过最后要提醒的一点是,在用form表单提交文件时,必须加上enctype=”multipart/form-data”属性。而后台必须加上解析formdata的相关文件,express中加上app.use(require('connect-multiparty')());//专门处理enctype="multipart/form-data"文件