前后端交互 - 上传文件

上传文件

依赖于 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 = "接收成功";
	})

图片说明:
前后端交互 - 上传文件_第1张图片


获取文件并将其渲染到页面 ( 图片为例 )

因为只是简单的测试效果
所以直接将html文件放到了static文件夹下
方便测试
文件夹放置如下:
前后端交互 - 上传文件_第2张图片

  • 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= `${
       imgUrl}">`
                if (i >= imgObj.length) {
     
                    i = 0
                }
            }
		xhr.send()
	}

你可能感兴趣的:(node.js,客户端交互)