Web前端 Js文件上传类型限制(根据文件头信息判断)

前言

在Web项目开发过程中,文件上传功能几乎必不可少的,很多时候,我们在进行文件上传时,尤其是向普通用户开放文件上传功能时,一般都需要对上传文件的格式进行一些限制,以防止不良用户、黑客等将带有病毒脚本文件上传到服务器中,常见文件格式限制如下。

1、通过input标签的accept属性进行限制

我们可以通过HTML5中的 input file 标签的accept属性,根据自己的需求,在选择上传文件的时候,指定可见的文件类型格式(默认任意类型 )来进行限制。

实例代码:


<input type="file" id="oFile" name="myFiles" accept=".doc, .docx, .xls, .txt" onchange="upFile(event)" />

2、通过JS获取上传文件的file.type 或 file.name属性进行限制

在JS中,可以在上传事件中,通过file对象获取到上传文件的相关属性。

实例代码:


function upFile(event) {
	const [ file ] = event.target.files || event.dataTransfer.files || this.file.files;
	
	console.dir(file); // 文件对象
	console.log(file.name); // 文件名称  
	console.log(file.type); // 文件类型
    console.log(file.size); // 文件大小
	
	// 对文件类型做简单限制:如:只允许上传 jpg  png gif 这3种格式
	if(!file.type && /\.(?:jpg|png|gif)$/.test(file.name)) ){ 
	    alert('对不起:上传的图片格式只能是:jpg, png, gif 格式!'); 
    	return false; 
    } 
}

以上两种方式是我们最常见的文件上传类型限制方法,但是,如果单纯的以文件后缀名(扩展名)、文件类型进行截取的方式来进行限制,是非常容易遭到破解的,比如,用户要将文件的后缀名(扩展名),重命为你指定的可上传的文件类型,就绕过了你的限制,便可以完成上传。

此时:我们根据文件的头信息,来判断文件真正的格式。

3、通过JS的FileReader方法获取上传文件的头信息进行限制

在JS中通过读取文件的十六进制的头信息,来进行限制,因为相同类型文件的文件头信息是相同的,即使用户修改了文件的后缀名(扩展名),但文件的头信息是不会改变的。

实例代码:

// 读取文件的二进制数据并将其转换为十六进制
function fileReader (blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsBinaryString(blob);
    reader.onload = (ret) => {
      const res = reader.result.split('').map((o) => o.charCodeAt().toString(16).padStart(2, '0'));
      resolve(res.join(' ').toUpperCase());
    },
    reader.onerror = (err) => {
      reject(err);
    };
  });
};

// png格式
async function isPng(file) {
  return (await fileReader(file.slice(0, 8))) == "89 50 4E 47 0D 0A 1A 0A";
};

// jpg格式
async function isJpg(file) {
  const start = await fileReader(file.slice(0, 2));
  const end = await fileReader(file.slice(-2, file.size));
  return "FF D8" == start && "FF D9" == end;
};

// gif格式
async function isGif(file) {
  const ret = await fileReader(file.slice(0, 6));
  return "47 49 46 38 39 61" == ret || "47 49 46 38 37 61" == ret;
};

async function upFile(event) {
	const [ file ] = event.target.files || event.dataTransfer.files || this.file.files;
	
	console.dir(file); // 文件对象
	console.log(file.name); // 文件名称  
	console.log(file.type); // 文件类型
    console.log(file.size); // 文件大小
	
	// 根据文件头信息进行判断限制:如:只允许上传 png 这种格式
	if(!await isPng(file)){ 
	    alert('对不起:上传的图片格式只能是:png格式!'); 
    	return false; 
    }
}

4、通过第三方的file-type工具包来进行限制

file-type工具包也是用Js来进行封装的,其原理和上面的第3种方式一样,它支持的文件类型有几十种,几乎能满足我们的日常开发需求。

Npm地址:https://www.npmjs.com/package/file-type

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,Web前端像上传的实现可以使用HTML5中的FormData对象和XMLHttpRequest对象来完成,具体步骤如下: 1.在HTML页面中,添加一个包含上传按钮的表单: ```html <form id="avatar-form"> <input type="file" id="avatar-input" name="avatar"> <button type="submit">上传</button> </form> ``` 2.在JavaScript中,获取表单元素和文件输入元素,并注册表单提交事件: ```javascript const form = document.querySelector('#avatar-form'); const input = document.querySelector('#avatar-input'); form.addEventListener('submit', (event) => { event.preventDefault(); // 阻止表单的默认提交行为 const formData = new FormData(); // 创建FormData对象 formData.append('avatar', input.files[0]); // 添加文件到formData中 uploadAvatar(formData); // 调用上传函数 }); ``` 3.定义上传函数,使用XMLHttpRequest发送POST请求: ```javascript function uploadAvatar(formData) { const xhr = new XMLHttpRequest(); xhr.open('POST', '/api/upload/avatar', true); xhr.setRequestHeader('Content-Type', 'multipart/form-data'); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { console.log('上传成功'); } }; xhr.send(formData); } ``` 4.在后端服务器中,接收上传的文件并进行处理。例如使用Node.js的Express框架: ```javascript const express = require('express'); const multer = require('multer'); const app = express(); const upload = multer({ dest: 'uploads/' }); // 指定文件存储目录 app.post('/api/upload/avatar', upload.single('avatar'), (req, res) => { const file = req.file; // 获取上传的文件信息 // 处理上传的文件,并返回结果 res.json({ success: true }); }); app.listen(3000, () => { console.log('服务器已启动'); }); ``` 以上是一个简单的Web前端像上传的实现例子,需要注意的是,上传文件时应该注意文件大小的限制,以及后端服务器的安全配置。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值