在前端开发中,文件上传是一个常见的需求,Common.js 作为一种模块化的 JavaScript 文件,可以用于封装和复用上传相关的代码逻辑,以下是关于 common.js 上传的详细解释:
1、基础设置
创建文件输入框:在 HTML 中创建一个<input>
元素,其type
属性设置为file
,并为其设置一个唯一的id
或name
属性,以便在 JavaScript 中获取该元素的引用。<input type="file" id="fileInput">
获取文件输入框引用:在 JavaScript 中使用document.getElementById()
方法或其他选择器方法,根据前面设置的id
或name
获取文件输入框的引用,并将其存储在一个变量中,这样可以通过这个变量来监听文件输入框的事件以及获取用户选择的文件。var fileInput = document.getElementById('fileInput');
2、事件监听与处理
监听文件选择事件:使用addEventListener
方法为文件输入框添加change
事件监听器,当用户选择文件后,会触发这个事件,然后在事件处理函数中编写处理文件上传的逻辑。fileInput.addEventListener('change', function () {...});
获取选择的文件:在事件处理函数中,通过fileInput.files
属性可以获取到一个FileList
对象,其中包含了用户选择的所有文件,通常我们只需要处理第一个文件,可以使用fileInput.files[0]
来获取单个文件对象。
3、文件上传方式
使用 FormData 对象:
创建 FormData 实例:将获取到的文件对象作为参数传递给FormData
的构造函数,创建一个FormData
对象。var formData = new FormData(); formData.append('file', file);
发送请求:可以使用XMLHttpRequest
或fetch
API 来发送包含文件数据的请求,如果使用XMLHttpRequest
,需要先创建一个新的XMLHttpRequest
对象,然后配置请求的方法(如POST
)、URL 以及是否异步等参数,接着将formData
作为请求体发送出去,并监听请求的状态变化,在请求完成且状态为 200 时,表示上传成功,可以在回调函数中进行相应的处理,如果使用fetch
,则可以直接将formData
作为请求的body
选项的值,然后发送请求,并在then
方法中处理响应结果。
使用 XMLHttpRequest:
var xhr = new XMLHttpRequest(); xhr.open('POST', '上传的 URL', true); xhr.onload = function () { if (xhr.status === 200) { console.log('上传成功'); } }; xhr.send(formData);
使用 fetch:
fetch('上传的 URL', { method: 'POST', body: formData }).then(response => { if (response.ok) { console.log('上传成功'); } });
使用第三方库(如 axios):
安装 axios:如果项目中还没有安装 axios,可以使用包管理工具(如 npm 或 yarn)安装它,例如使用 npm 安装的命令为:npm install axios
发送请求:引入 axios 模块后,可以使用axios.post
方法发送包含文件数据的请求,同样需要将formData
作为第二个参数传递给post
方法,并指定请求的 URL。
import axios from 'axios'; axios.post('上传的 URL', formData).then(response => { if (response.status === 200) { console.log('上传成功'); } });
4、大文件上传处理
分块上传原理:对于大文件,为了避免一次性上传造成网络阻塞或超时等问题,通常会采用分块上传的方式,将大文件按照一定的大小(如每块 1MB)分割成多个小块,然后逐个上传这些小块到服务器,服务器端接收到所有小块后,再将它们合并成完整的文件。
实现步骤
计算分块信息:根据文件的总大小和设定的分块大小,计算出需要分成的块数以及每块的起始和结束位置,如果文件大小为 5MB,分块大小为 1MB,则需要分成 5 块,每块的大小为 1MB。
遍历分块并上传:使用循环结构遍历每个分块,对于每个分块,使用File
对象的slice
方法截取对应的数据块,然后按照上述的文件上传方式将每个数据块上传到服务器,在上传每个分块时,需要在请求头中设置Content-Range
字段,指定当前上传的是文件的哪个部分。xhr.setRequestHeader('Content-Range', 'bytes ' + start + '-' + end + '/' + file.size);
处理服务器端合并:服务器端需要有相应的逻辑来接收分块数据,并将它们存储在临时位置,当接收到所有分块后,按照分块的顺序将它们合并成一个完整的文件。
5、跨域问题处理
CORS 设置:如果在文件上传过程中涉及到跨域请求,可能会遇到浏览器的同源策略限制,为了解决这个问题,服务器端需要在响应头中添加适当的 CORS 相关字段,如Access-Control-Allow-Origin
、Access-Control-Allow-Methods
、Access-Control-Allow-Headers
等,以允许来自不同源的请求访问资源,如果允许来自所有域名的请求访问接口,服务器端可以设置:header('Access-Control-Allow-Origin', '');
withCredentials 属性:在某些情况下,如果需要在跨域请求中携带 cookies 等身份验证信息,可以将XMLHttpRequest
对象的withCredentials
属性设置为true
,但此时服务器端响应头中的Access-Control-Allow-Origin
不能设置为,而必须是具体的请求域名。
xhr.withCredentials = true;
common.js 中的上传功能涉及多个方面,包括基础设置、事件监听与处理、文件上传方式、大文件上传处理以及跨域问题处理等,通过合理地组合和运用这些技术手段,可以实现高效、稳定的文件上传功能。