JavaScript: อัพโหลดไฟล์


189

สมมติว่าฉันมีองค์ประกอบนี้ในหน้า:

<input id="image-file" type="file" />

สิ่งนี้จะสร้างปุ่มที่อนุญาตให้ผู้ใช้เว็บเพจเลือกไฟล์ผ่านทางกล่องโต้ตอบ "เปิดไฟล์ ... " ในเบราว์เซอร์

สมมติว่าผู้ใช้คลิกปุ่มบอกว่าเลือกไฟล์ในกล่องโต้ตอบจากนั้นคลิกปุ่ม "ตกลง" เพื่อปิดกล่องโต้ตอบ

ชื่อไฟล์ที่เลือกจะถูกจัดเก็บใน:

document.getElementById("image-file").value

ตอนนี้สมมติว่าเซิร์ฟเวอร์จัดการ POST หลายส่วนที่ URL "/ upload / image"

ฉันจะส่งไฟล์ไปยัง "/ upload / image" ได้อย่างไร?

นอกจากนี้ฉันจะฟังการแจ้งเตือนว่าไฟล์อัพโหลดเสร็จได้อย่างไร


2
JavaScript ไม่ได้จัดการการอัปโหลดเนื่องจากเป็นเซิร์ฟเวอร์ สคริปต์ฝั่งเซิร์ฟเวอร์จะรับไฟล์จากนั้นย้ายไฟล์ สำหรับ php จากโฟลเดอร์ชั่วคราวไปยังโฟลเดอร์ที่ต้องการ
บากู


15
โหวตให้เปิดใหม่อีกครั้งเนื่องจากคำถามเกี่ยวกับ POJS (จาวาสคริปต์แบบธรรมดาธรรมดา) ไม่ใช่ jQuery
e2-e4

คำตอบ:


95

ถ้าคุณกำลังพยายามที่จะอัปโหลดไฟล์โดยใช้ Ajax เพียงแค่ส่งแบบฟอร์ม/upload/imageการ

<form enctype="multipart/form-data" action="/upload/image" method="post">
    <input id="image-file" type="file" />
</form>

หากคุณต้องการอัพโหลดภาพในพื้นหลัง (เช่นโดยไม่ต้องส่งแบบฟอร์มทั้งหมด) คุณสามารถใช้ ajax:


หรือขนาด iframe 0x0 พร้อมสคริปต์อัพโหลดภาพภายใน src = "" และโพสต์แบบฟอร์มโดยใช้ target = "iframeId" อ่านผลลัพธ์กลับมาบนเหตุการณ์ iframe src .load ซึ่งสามารถผูกไว้โดยใช้ jQuery ตัวอย่างเช่น
Dmitry

11
เป็นไปได้จริงที่จะอัปโหลดผ่าน Javascript และ Ajax ทุกวันนี้โปรดดู: stackoverflow.com/a/10811427/694469 (ฉันไม่ได้ลงคะแนน)
KajMagnus

35
@KajMagnus คุณอาจหมายถึง 'อัพโหลด' แต่ตั้งใจว่า 'upvote' โดยบังเอิญ
Samuel Allan

85

เพียว JS

คุณสามารถใช้การดึงข้อมูลแบบเลือกรอได้

let photo = document.getElementById("image-file").files[0];
let formData = new FormData();

formData.append("photo", photo);
fetch('/upload/image', {method: "POST", body: formData});

แนวทางโรงเรียนเก่า - xhr

let photo = document.getElementById("image-file").files[0];  // file from input
let req = new XMLHttpRequest();
let formData = new FormData();

formData.append("photo", photo);                                
req.open("POST", '/upload/image');
req.send(formData);

สรุป

  • ในฝั่งเซิร์ฟเวอร์คุณสามารถอ่านชื่อไฟล์ต้นฉบับ (และข้อมูลอื่น ๆ ) ซึ่งรวมอยู่โดยอัตโนมัติเพื่อร้องขอโดยเบราว์เซอร์ในfilenameพารามิเตอร์ formData
  • คุณไม่จำเป็นต้องตั้งค่าส่วนหัวคำขอContent-Typeเป็นmultipart/form-data- เบราว์เซอร์นี้จะถูกตั้งค่าโดยอัตโนมัติ
  • แทนการที่คุณสามารถใช้ที่อยู่เต็มเช่น/upload/imagehttp://.../upload/image
  • หากคุณต้องการส่งไฟล์จำนวนมากในแอmultipleททริบิวต์คำขอใช้ครั้งเดียว: <input multiple type=... />และแนบไฟล์ที่เลือกทั้งหมดไปยัง formData ด้วยวิธีที่คล้ายกัน (เช่นphoto2=...files[2];... formData.append("photo2", photo2);)
  • คุณสามารถรวมข้อมูลเพิ่มเติม (json) เพื่อขอเช่นlet user = {name:'john', age:34}ในวิธีนี้:formData.append("user", JSON.stringify(user));
  • โซลูชันนี้ควรทำงานกับเบราว์เซอร์หลักทั้งหมด

ทำงานอย่างสมบูรณ์แบบสำหรับฉัน
Trieu Nguyen

formData === ส่งแบบฟอร์มenctype="multipart/form-data"
xgqfrms

ฉันได้รับข้อผิดพลาดnet::ERR_ABORTED 405 (Method Not Allowed)
Hidayt Rahman

@HidaytRahman ข้อผิดพลาดนี้มักจะปรากฏขึ้นเมื่อ serwer ไม่ได้ใช้วิธีการโพสต์สำหรับ URL ของคุณ
Kamil Kiełczewski

1
แปลก - ตามที่คุณคิดฉันคิดว่าเราไม่ต้องการเซิร์ฟเวอร์อีกต่อไป: D
Hidayt Rahman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.