Play Open
Loading Please wait Loading Please wait Loading Please wait Loading Please wait Loading Please wait Loading Please wait

Ajax基础到实战(四)——formData对象_ajax formdata

Formdata 对象不能用于 get 请求,因为对象需要被传递到 send 方法中,而 get 请求方式的请求参数只能放在请求地址的后面。服务器端 bodyParser 模块不能解析 formData 对象表单数据,我们需要使用 formidable 模块进行解析。

formData对象的简单使用:

05.formData表单的使用方法.html

Document

在 app.js 文件中添加路由:

// 引入express框架

const express = require('express');

// 路径处理模块

const path = require('path');

const formidable = require('formidable');

// 创建web服务器

const app = express();

// 静态资源访问服务功能

app.use(express.static(path.join(__dirname, 'public')));

app.post('/formData', (req, res) => {

// 创建formidable表单解析对象

const form = new formidable.IncomingForm();

// 解析客户端传递过来的FormData对象

form.parse(req, (err, fields, files) => {

res.send(fields);

});

});

注意上面引入了 formidable 模块来解析 formData 对象表单数据。

在浏览器中输入:

http://localhost:3000/05.formData表单的使用方法.html

在表单中填入信息,点击提交按钮,可以看到浏览器控制台输出了表单中的信息,也即post请求的参数,而且是以对象的形式输出的。

3. formData对象实例方法

获取表单对象中的属性值

formData.get('key')

在 xhr.onclick中添加上述代码

06.formData对象实例方法.html

Document

最终可以在浏览器中看到username属性的属性值

设置表单对象中的属性值

formData.set('key', 'value')

在上述代码的基础上添加一行代码:

console.log(formData.get('username'));

formData.set('username', 'itcast');

最终可以看到 username 的属性值被设置为了 itcast,无论用户在表单中输入的值是什么最终都是 itcast

再在程序后面加上一行:

console.log(formData.get('username'));

// 如果设置的表单属性存在,会替换原来的表单属性值

formData.set('username', 'itcast');

// 如果设置的表单属性不存在,将会创建这个表单属性

formData.set('age', '20');

此时可以看到多了age属性,这是直接创建的新属性。

3. 删除表单对象中属性的值

formData.delete('key');

在上面的程序中载入一行代码:

var formData = new FormData(form);

// get('key') 获取表单对象属性的值

// set('key', 'value') 设置表单对象的值

// delete('key') 删除表单对象属性中的值

console.log(formData.get('username'));

// 如果设置的表单属性存在,会替换原来的表单属性值

formData.set('username', 'itcast');

// 如果设置的表单属性不存在,将会创建这个表单属性

formData.set('age', '20');

// 删除用户输入的密码

formData.delete('password');

浏览器中输出的结果如下图所示:

password 这个参数在传递给服务器端之前就已经删除了,因此可以看到在最终的输出结果中是没有看到 pasword 这个属性的。 4. 向表单中追加属性值

formData.append('key', 'value')

添加两行代码进行测试:

xhr.onload = function () {

// 对象http状态码进行判断

if (xhr.status == 200) {

console.log(xhr.responseText);

}

// 创建空的表单对象

var f = new FormData();

f.append('sex', '男');

console.log(f.get('sex'));

}

可以得到如下的输出结果:

我们发现get方法和set方法比较类似,其实两者还是有一些区别的:

set 方法在属性名已存在的情况下会覆盖已有键名的值append 方法在属性名已存在的情况下会保留两个值

在原有代码的基础上再添加代码:

btn.onclick = function () {

// 将普通的html表单转换为表单对象

var formData = new FormData(form);

// get('key') 获取表单对象属性的值

// set('key', 'value') 设置表单对象的值

// delete('key') 删除表单对象属性中的值

console.log(formData.get('username'));

// 如果设置的表单属性存在,会替换原来的表单属性值

formData.set('username', 'itcast');

formData.append('username', 'itheima');

// 如果设置的表单属性不存在,将会创建这个表单属性

formData.set('age', '20');

// 删除用户输入的密码

formData.delete('password');

// 创建ajax对象

var xhr = new XMLHttpRequest();

// 对ajax对象进行配置

xhr.open('post', 'http://localhost:3000/formData');

// 发送ajax请求

xhr.send(formData);

// 监听xhr对象下的onload事件

xhr.onload = function () {

// 对象http状态码进行判断

if (xhr.status == 200) {

console.log(xhr.responseText);

}

// 创建空的表单对象

var f = new FormData();

f.append('sex', '男');

console.log(f.get('sex'));

}

}

浏览器的控制台输出结果如下:

看到结果我们可能会有一些疑问,为什么username的属性值最终输出为什么只有一个,虽然先set了属性值为itcast,随后append了itheima,理论上这两个应该都会有啊?最终只显示一个是因为服务器端最终会以返回最后面的属性值,实际上我们可以在控制台的 Form Data 中看到两个属性值都是存在的:

4. FormData二进制文件上传

客户端的核心代码

var file = document.getElementById('file');

// 当用户选择文件的时候

file.onchange = function () {

// 创建空表单对象

var formData = new FormData();

// 将用户选择的二进制文件追加到表单对象中

formData.append("attrName", this.files[0];

// 配置ajax对象,请求方式必须为post

xhr.open('post', 'www.example.com');

xhr.send();

}

07.FormData对象实现二进制文件上传.html

Document

app.js 文件:

// 引入express框架

const express = require('express');

// 路径处理模块

const path = require('path');

const formidable = require('formidable');

// 创建web服务器

const app = express();

// 静态资源访问服务功能

app.use(express.static(path.join(__dirname, 'public')));

// 实现文件上传的路由

app.post('/upload', (req, res) => {

// 创建formidable表单解析对象

const form = new formidable.IncomingForm();

// 设置客户端上传文件的存储路径

form.uploadDir = path.join(__dirname, 'public', 'uploads');

// 保留上传文件的后缀名字

form.keepExtensions = true;

// 解析客户端传递过来的FormData对象

form.parse(req, (err, fields, files) => {

// 将客户端传递过来的文件地址响应到客户端

res.send('ok');

});

});

可以在public文件夹下的 uploads 文件夹中看到上传的视频文件:

5. FormData 文件上传进度展示

核心代码:

// 当用户选择文件的时候

file.onchange = function () {

// 文件上传过程中持续触发 onprogress 事件

xhr.upload.onprogress = function () {

// 当前上传文件大小/文件总大小,再将结果转换为百分比

// 将结果赋值给进度的宽度属性

bar.style.width = (ev.onload / ev.total) \* 100 + '%';

}

}

在ajax对象 xhr 中有upload属性,upload属性中有关于文件上传的一些事件,在文件上传的过程中可以持续触发onprogress事件,在这个事件的事件对象中我们可以看到 ev.loaded 以及 ev.total 这两个事件对象的属性,分别代表当前文件上传的大小以及上传文件的总大小,我们可以据此计算出文件上传的进度并以百分比的形式显示在页面中。

在07html页面中添加进度条单元:

0%

且进度条的初始宽度设置为0。

Document

0%

app.js 文件不变,还是上面没有进度条时的。

最终的上传进度条效果成功实现了

且上传成功,控制台输出了 ok

6. ForaData 文件上传图片及时预览

将客户端传递过来的文件地址响应到客户端 我们可以在浏览器页面上传文件,同时在浏览器控制台打印出上传成功后的文件在硬盘中的绝对路径,也就是文件地址。

我们在上传文件的时候给formData对象下面添加了一个attrName 属性,其属性值对应的就是上传的二进制文件,因此我们可以使用:

files.attrName.path 得到文件上传后的路径

// 实现文件上传的路由

app.post('/upload', (req, res) => {

// 创建formidable表单解析对象

const form = new formidable.IncomingForm();

// 设置客户端上传文件的存储路径

form.uploadDir = path.join(__dirname, 'public', 'uploads');

// 保留上传文件的后缀名字

form.keepExtensions = true;

// 解析客户端传递过来的FormData对象

form.parse(req, (err, fields, files) => {

// 将客户端传递过来的文件地址响应到客户端

res.send(files.attrName.path);

});

});

我们上传了一张图片可以看到浏览器控制台输出了文件的地址,我们知道public文件夹下存放的就是服务器端的静态资源,是可以提供给用户进行访问的,我们可以使用字符串分割的方法对文件的地址进行分割后得到其静态资源文件地址,这样我们就可以访问到这些上传的文件了。

E:\迅雷下载\nodejs(前端就业班--阶段3)\源码+课件(黑马)\tpl\public\uploads\upload_5e4db6a7be4b1728317188109fd5ccd3.jpg

针对这个地址,我们可以以存放静态资源的文件夹名称 public 作为字符串的分隔符。

// 实现文件上传的路由

app.post('/upload', (req, res) => {

// 创建formidable表单解析对象

const form = new formidable.IncomingForm();

// 设置客户端上传文件的存储路径

form.uploadDir = path.join(__dirname, 'public', 'uploads');

// 保留上传文件的后缀名字

form.keepExtensions = true;

// 解析客户端传递过来的FormData对象

form.parse(req, (err, fields, files) => {

// 将客户端传递过来的文件地址响应到客户端

res.send(

{

path: files.attrName.path.split('public')[1]

});

});

});

将分割后的地址保存在对象下的 path 属性中。

图片上传成功后实时预览 我们可以在html页面中添加一个div来放置图片容器

Posted in 14年巴西世界杯
Previous
All posts
Next