上传文件
依赖于 input 标签的 file 控件及FormData对象
上传文件
HTML页面准备
<input type="file" class="myfile">
<button>点击上传文件</button>
前端js准备
- FormData对象
这里以提交图片为例。
提交大批量的数据 ( 文件,图片 ) 通常建议使用post方法,这种情况下不可避免的需要设置请求头。
这里的我们引入FormData对象,它会自动设置请求头,提高开发效率。
document.querySelector("button").onclick = function(){
// 获取上传的文件 得到的数据是 数组的形式
let file = document.querySelector(".myfile").files[0];
// console.log(file)
// 创建FromData对象 不需要设置头部信息
let form = new FormData();
// 添加文件
// 将需要上传的文件信息,以键值对方式(属性名,属性值)写入
form.append("img",file);
// 也可用来上传数据
form.append("usernam","兟");
let xhr = new XMLHttpRequest();
// get 上传的文件都在 url 头部 无法上传文件
// 文件上传 需要通过 正文的方式提交
xhr.open("post","/upload",true);
xhr.onload = function(){
console.log(xhr.responseText)
}
xhr.send(form) // 将数据发送到后端服务器
}
后端服务器准备
// 记得开启 koaBody的multipart属性 否则无法获取上传的文件数据
app.use(koaBody({
multipart : true
}));
---------------------------------------------------------------
router.post("/upload",async ctx=>{
// 通过 koa-body 模块 获得的数据,并不是 ctx 自带的
// console.log(ctx.request.body)
// .img 是因为页面 上传时候 添加的属性名为img
console.log(ctx.request.files.img)
// 读取
let fileData = fs.readFileSync(ctx.request.files.img.path);
// 写入 其实质就是 复制一份文件到 static/img_upload文件夹下
fs.writeFileSync("static/img_upload/"+ctx.request.files.img.name,fileData);
ctx.body = "接收成功";
})
图片说明:
获取文件并将其渲染到页面 ( 图片为例 )
因为只是简单的测试效果
所以直接将html文件放到了static文件夹下
方便测试
文件夹放置如下:
- img_upload文件夹 上传的图片的存储位置
- imgs文件夹 自带的图片(暂不考虑)
整个操作的实质 :将图片复制到指定文件夹下,然后读取,显示到页面
后端搭建服务器
const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");
const fs = require("fs"); //操作文件
const koaBody = require("koa-body");
let app = new Koa();
let router = new Router();
// 上传文件 必须开启配置对象
app.use(koaBody({
multipart : true
}));
app.use(static(__dirname+"/static"));
router.post("/upload",async ctx=>{
// 读取文件
// .img 是因为页面 上传时候 添加的属性名为img
// console.log(ctx.request.files.img)
let fileData = fs.readFileSync(ctx.request.files.img.path);
let imgurl = "/img_upload/"+ctx.request.files.img.name;
// 写入
fs.writeFileSync("static/img_upload/"+ctx.request.files.img.name,fileData);
ctx.body = "接收成功";
})
// 服务端 返回图片 页面显示
router.get("/imgShow",async ctx=>{
// 读取上传图片的那个文件夹 (img_upload)
//读取的数据为 数组的形式
let imgData = fs.readdirSync("static/img_upload");
ctx.body = {
info:imgData
}
})
app.use(router.routes());
app.listen(7692);
前端页面准备
<style>
.img {
width: 500px;
height: 300px;
background-color: cyan;
padding: 10px;
}
.img>img {
width: 100%;
height: 100%;
}
</style>
-------------------------------------------
<div class="img">
<img src="./imgs/1.jpg" alt="">
</div>
<button>图片显示</button>
JS代码
let i = 0;
document.querySelector("button").onclick = function(){
let xhr = new XMLHttpRequest();
xhr.open("get", "/imgShow", true);
xhr.onload = function () {
// 接收的页面数据格式 字符串形式的 { info : imgData }
// 需要 先将接收到的数据 转换为 对象的形式
let imgObj = JSON.parse(xhr.responseText).info;
let imgUrl = "./img_upload/"+imgObj[ i >= imgObj.length ? 0 : i++];
// 点击按钮 去循环展示图片
document.querySelector(".img").innerHTML= `<img src="${imgUrl}">`
if (i >= imgObj.length) {
i = 0
}
}
xhr.send()
}