이 기사는 기존 개발 모드 업로드, 프런트엔드 및 백엔드 별도 업로드, Ajax 업로드 및 기타 관련 문제를 포함하여 프런트엔드 업로드 파일에 대한 관련 지식을 제공합니다.
프로젝트에는 아바타 업로드, 테이블 파일, 워드 문서 등 다양한 파일 업로드 요구 사항이 있습니다.
업로드에 필요한 양식 요소:
<input>
파일 업로드 시 ,
1 .양식은 반드시 post 요청이어야 합니다
2. 양식은 데이터를 인코딩하지 않도록 선언해야 합니다 - enctype=multipart/form-data
전송되는 데이터의 형식은 키-값 쌍의 형태이며, data는 모두 js 데이터 유형이지만 파일은 전송할 때 전송 형식이 두 가지뿐입니다.
프런트엔드와 백엔드 혼합 개발
기존 개발 모델에서 업로드하려면 양식에서 선택한 파일을 백엔드로 전송하고 백엔드에서 업로드를 수행해야 합니다.
이때, 양식에는 enctype 속성이 있어야 합니다.
업로드 버튼을 클릭하면 백엔드가 파일을 업로드합니다. PHP를 예로 들어보겠습니다.
echo "上传文件名: " . $_FILES["avatar"]["name"] . "<br>"; 上传文件的名称 echo "文件类型: " . $_FILES["avatar"]["type"] . "<br>"; 上传文件的类型 echo "文件大小: " . ($_FILES["avatar"]["size"] / 1024) . " kB<br>"; 上传文件的大小,以字节计 echo "文件临时存储的位置: " . $_FILES["avatar"]["tmp_name"]; 存储在服务器的文件的临时副本的名称 echo $_FILES["file"]["error"] 由文件上传导致的错误代码
파일을 서버에 저장합니다. :
move_uploaded_file($_FILES["avatar"]["tmp_name"], "upload/" . $_FILES["avatar"]["name"]); echo "文件存储在: " . "upload/" . $_FILES["avatar"]["name"];
실제 개발에서는 효율성을 높이기 위해 프론트엔드와 백엔드 분리 개발을 주로 사용합니다.
프런트엔드는 프론트엔드, 백엔드는 백엔드, 마지막으로 인터페이스 문서를 도킹에 사용 - 핵심기술은 ajax
프론트엔드와 백엔드는 별도로 개발되며, 주로 사용되는 기술은 ajax입니다. 업로드는 ajax를 통해서도 가능합니다.
FormData는 js에 내장된 생성자이며 생성된 객체는 파일 정보를 식별할 수 있습니다.
사용법:
FormData 개체를 구성하고 FormData 개체에 파일 정보를 추가한 다음 업로드합니다.
파일 정보는 파일 선택 컨트롤에 있습니다: form.files
예:
<input> <input><script>document.querySelector('[type="button"]').onclick = function(){ console.log(document.querySelector('[type="file"]').files)}</script>
FormData 개체에는 파일 정보를 추가한 후 직접 인쇄할 때 파일 정보를 볼 수 없는 기능이 필요합니다. 순회를 사용하려면 다음을 참조하세요.
var formdata = new FormData();var fileinfo = document.querySelector('[type="file"]').files[0];formdata.append('avatar',fileinfo) / 将文件信息添加到FormData对象中 console.log(formdata)for(var v of formdata){ console.log(v)}
FormData 객체에 다른 데이터를 추가하고 함께 제출할 수도 있습니다.
formdata.append('avatar',fileinfo)formdata.append('age',12)for(var v of formdata){ console.log(v)}
FormData 객체에서 데이터 조각을 삭제하려면 다음을 사용하세요. :
formdata.delete(键)
경우에 따라 여러 파일을 업로드해야 하는 경우가 있습니다. 이때 FormData 개체를 구성할 때 전체 양식 개체를 전달할 수 있으며, 모든 데이터를 자동으로 인식합니다.
FormData를 사용하여 업로드하는 경우 FormData 개체를 데이터로 전달할 때 요청 헤더를 수정할 필요가 없으며 브라우저가 자동으로 수정합니다.
현재 프론트엔드와 백엔드의 별도 업로드가 구현되어 있지만 일반 프로젝트에서는 이미지를 미리 볼 수 있는 기능이 있습니다.
업로드 후 백엔드에서 업로드된 파일 이름을 프런트엔드로 전송하고 프런트엔드에서 반환된 이미지 경로를 렌더링하도록 할 수 있습니다.
하지만 이는 업로드 후 미리보기를 위한 것입니다. 파일을 선택한 후 업로드해야 하는지 확인하고 싶다면 업로드하기 전에 미리 볼 수 있는 방법이 없습니다.
H5에서 제공하는 FileReader를 사용하여 파일을 읽고 미리 본 후 업로드 여부를 결정할 수 있습니다.
ajax 업로드 후
var xhr = new XMLHttpRequest; xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ if(xhr.status>=200 && xhr.status<p>전송을 위해 파일 데이터를 send에 넣습니다<br> H5에서 제공하는 FormData 생성자를 사용해야 합니다. 파일 정보를 식별하는 데 사용됩니다.</p><pre class="brush:php;toolbar:false">var fd = new FormData()
파일 정보를 fd에 넣습니다. object Medium - fd의 추가 방식 사용
파일 정보는 어디에 있나요?
var file = document.querySelector('[type="file"]') // console.dir(file); var fileinfo = file.files[0] / 文件信息
append 메소드는 이 객체에 파일을 넣는 것입니다. 객체에는 키-값 쌍이 필요합니다. 매개변수 1은 키이고 매개변수 2는 파일 정보입니다. 콘텐츠를 보려면 데이터를 보려면 of
fd.append('avatar',fileinfo)
fd를 사용해야 합니다. 파일 정보를 추가하는 것 외에도 데이터를 추가할 수도 있습니다
fd.append('username',document.querySelector('[name="username"]').value)
上传文件的时候,利用FormData,里面就有了数据和文件信息,其实最终文件和数据以二进制数据流进行传送的,不需要设置请求头,因为ajax会自动调整
文件数据其实就是fd
php:
现在能打印出数据,文件存到了临时目录中
上传就是将临时文件移动到服务器中
header("content-type:text/html;charset=utf8");echo "<pre class="brush:php;toolbar:false">";print_r($_FILES);move_uploaded_file($_FILES['avatar']['tmp_name'],'./upload/'.$_FILES['avatar']['name']);// echo '上传成功';echo './upload/'.$_FILES['avatar']['name']; echo "<script> alert('上传成功') location.assign('./1-上传表单.html')</script>
ajax 上传前:
当文件选择器中的数据发生了变化就要读取并预览
读取并预览 - 借助H5提供的FileReader - 读取文件是异步读取
构造函数需要new
document.querySelector('[type="file"]').onchange = function(){var fr = new FileReader();
readAsArrayBuffer - 将数据读取成一个Buffer数组
var fileinfo = this.files[0]
参数要一个文件对象 - 结果是一个buffer
fr.readAsArrayBuffer(fileinfo)
参数要一个文件对象 - 结果是一个二进制数据 - 适用于多媒体文件
fr.readAsBinaryString(fileinfo)
结果是一个可以当做路径使用的数据 - base64字符串 - 适用于图片
fr.readAsDataURL(fileinfo)
在load事件中,读取完成后获取读取出来的数据
load事件在读取完成的时候触发
fr.onload = function(){ / result属性是读取出来的内容 / console.log(fr.result); / 创建img标签 var img = document.createElement('img') img.src = fr.result; document.body.appendChild(img)
FileReader也是js内置的一个构造函数,主要功能是用来读取文件,读取文件为异步读取。
var fr = new FileReader() 创建读取对象// 该对象的读取方法:fr.readAsDataUrl(文件信息) 将文件读取为base64字符串 - 通常用于图片文件,读取结果可以作为图片的src使用 fr.readAsArrayBuffer(文件信息) 将文件读取为二进制数据流 - 通常用于多媒体文件 fr.readAsText(文件信息) 将文件读取为字符串 - 通常用于文档文件
对象监听的事件:
abort事件:在读取被中断的时候触发
error事件:读取发生错误的时候触发
load事件:在读取完成的时候触发 - 常用语读取完成后获取数据
loadstart事件:在读取开始的时候触发
loadend事件:在读取结束的时候触发
progress事件:在读取过程中触发
例:
fr.onload = function(){ 读取结果为:对象.result 或 事件对象.target.result console.log(fr.result) 此时这个数据就可以作为img的src进行图片预览}
base64是指:小写字母+大写字母+数字+加号+等于号 共64个字符
data位置就直接写formData就好了
设置一个content-type为false表示jquery不要设置请求头
设置一个processData为false,表示query不要修改数据格式
我们可以在new的时候,将表单元素放在构造函数中 - 默认能将表单中的数据,添加到这个对象中
$('[type="button"]').click(function() var fd = new FormData($('form')[0]) $.ajax({ url:"2-upload.php", method:"post", jquery上传用 FormData data:fd, contentType:false, 不让jQuery的ajax修改请求头 processData:false, 不让jquery的ajax编码数据 success:res=>{ console.log(res); } })})
大量运算的代码,可以作为一个异步线程执行
需要将这段代码单独放在一个文件中
需要new一个worker对象 - 这个构造函数需要在服务器环境中运行
woker需要一个事件,当文件完成以后获取里面的数据
可以在事件中,接收到文件中导出的数据
woker.onmessage = function(e){ 数据就在事件对象的data属性中 console.log(e.data);}
当业务逻辑需要的计算量比较大的时候,同步代码会阻塞下面的代码继续执行,此时需要将这个大计算量的代码另外开辟一个新的线程进行执行,这个线程也是异步执行的,但需要将在新线程中执行的代码单独放在一个js文件中,使用方式:
var w = new Worker(需要异步执行的js文件)
如果在主线程中需要这个线程中返回的数据,在这个线程中使用postMessage来返回:
postMessage(数据)
主线程中接收返回出来的数据:
w.onmessage = function(e){ e.data // 是异步线程中返回出来的数据}
离线缓存的作用:在马上断网之后,依旧可以访问到缓存下来的文件。比较鸡肋。该技术在2020年8月已经被弃用了。
使用方式:
使用规则 1. 需要你自定义一个 .manifest 文件 2. 再你书写 html 文件的时候 => 如果这个 html 文件需要缓存规则 => 再 html 标签上添加一个 manifest 属性 => 值就写你的缓存规则文件 3. 第一次打开页面的时候 => 就会按照你书写的缓存规则去缓存文件
例:
第一行必须要写上
CACHE MANIFEST
以注释的形式书写一个版本号
app version 1.0
表示你要缓存的文件
CACHE:
./index.html
./css/index.css
表示必须需要网络环境才可以请求的文件
一般我们会书写 星号(*), 表示除了 CACHE 里面书写的文件, 其他的去过没有网络环境就报错
NETWORK:
*
当你再一个离线环境下访问一些没有的页面的时候
使用一个什么内容替代
FALLBACK:
事件循环面试题:
<script>console.log(1)setTimeout(()=>{ console.log(2) },0) new Promise(resolve=>{ console.log(3) resolve()}).then(()=>{ console.log(4)})setTimeout(()=>{ console.log(5) new Promise(resolve=>{ console.log(6) setTimeout(()=>{ console.log(7) }) resolve() }).then(()=>{ console.log(8) })},500)new Promise(resolve=>{ console.log(9) resolve()}).then(()=>{ console.log(10) setTimeout(()=>{ console.log(11) },0)})console.log(12)</script>
答案:1 3 9 12 4 10 2 11 5 6 8 7
更多编程相关知识,请访问:编程视频!!
위 내용은 한 시간 후에 프론트 엔드에 파일을 업로드하는 방법(정리 및 공유)을 요약해 드리겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!