ฉันจะอัพโหลดไฟล์แบบอะซิงโครนัสได้อย่างไร


2914

ฉันต้องการอัพโหลดไฟล์แบบอะซิงโครนัสกับ jQuery

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

แทนที่จะอัปโหลดไฟล์ฉันได้รับชื่อไฟล์เท่านั้น ฉันจะแก้ไขปัญหานี้ได้อย่างไร


มีปลั๊กอินสำเร็จรูปที่หลากหลายในการอัปโหลดไฟล์สำหรับ jQuery การอัปโหลดแฮ็กแบบนี้ไม่ใช่ประสบการณ์ที่สนุกสนานดังนั้นผู้ใช้จึงเพลิดเพลินกับการใช้โซลูชั่นสำเร็จรูป นี่คือบางส่วน: - ตัวอัปโหลดไฟล์ JQuery - ปลั๊กอินอัปโหลดไฟล์หลายไฟล์ - อัปโหลดไฟล์หลายไฟล์ขนาดเล็ก - อัปโหลดไฟล์jQueryคุณสามารถค้นหาโครงการเพิ่มเติมเกี่ยวกับ NPM (โดยใช้ "jquery-plugin" เป็นคำหลัก) หรือ Github
Cheery

72
คุณได้รับชื่อไฟล์เพียงเพราะชื่อไฟล์ var ของคุณได้รับค่า $ ('# file') ไม่ใช่ไฟล์ที่อยู่ในอินพุต
Jimmy

21
ต่อไปนี้เป็นสิ่งที่ดี: http://blueimp.github.io/jQuery-File-Upload/ - การอัปโหลดอาแจ็กซ์ HTML5 - ทางเลือกที่ดีเยี่ยมสำหรับ iframe สำหรับเบราว์เซอร์ที่ไม่รองรับ - อัปโหลด async หลายไฟล์เราใช้มันและใช้งานได้ดี ( เอกสารที่นี่ )
Ashish Panery

3
ตรวจสอบนี้: stackoverflow.com/questions/6974684/ …ที่นี่มันอธิบายวิธีการบรรลุมันผ่าน jQuery
Chococroc

2
@ จิมมี่เขาจะได้รับไฟล์ที่อยู่ในอินพุทแทนได้อย่างไร?
alex

คำตอบ:


2519

ด้วยHTML5คุณสามารถทำการอัพโหลดไฟล์ด้วย Ajax และ jQuery ไม่เพียงแค่นั้นคุณสามารถทำการตรวจสอบความถูกต้องของไฟล์ (ชื่อขนาดและประเภท MIME) หรือจัดการเหตุการณ์ความคืบหน้าด้วยแท็กความคืบหน้า HTML5 (หรือ div) เมื่อเร็ว ๆ นี้ฉันต้องทำการอัปโหลดไฟล์ แต่ฉันไม่ต้องการใช้Flashหรือ Iframes หรือปลั๊กอินและหลังจากการวิจัยบางอย่างฉันก็พบวิธีแก้ปัญหา

ใช้ HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

ขั้นแรกคุณสามารถตรวจสอบความถูกต้องได้หากต้องการ ตัวอย่างเช่นใน.on('change')กรณีของไฟล์:

$(':file').on('change', function () {
  var file = this.files[0];

  if (file.size > 1024) {
    alert('max upload size is 1k');
  }

  // Also see .name, .type
});

ตอนนี้คลิก$.ajax()ส่งด้วยปุ่ม:

$(':button').on('click', function () {
  $.ajax({
    // Your server script to process the upload
    url: 'upload.php',
    type: 'POST',

    // Form data
    data: new FormData($('form')[0]),

    // Tell jQuery not to process data or worry about content-type
    // You *must* include these options!
    cache: false,
    contentType: false,
    processData: false,

    // Custom XMLHttpRequest
    xhr: function () {
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) {
        // For handling the progress of the upload
        myXhr.upload.addEventListener('progress', function (e) {
          if (e.lengthComputable) {
            $('progress').attr({
              value: e.loaded,
              max: e.total,
            });
          }
        }, false);
      }
      return myXhr;
    }
  });
});

อย่างที่คุณเห็นด้วยการอัปโหลดไฟล์ HTML5 (และการวิจัยบางอย่าง) ไม่เพียงเป็นไปได้ แต่ยังง่ายสุด ๆ ลองใช้กับGoogle Chromeเนื่องจากองค์ประกอบ HTML5 บางตัวอย่างไม่พร้อมใช้งานในทุกเบราว์เซอร์


14
ฉันสามารถใช้ $ _FILES ใน upload.php ได้หรือไม่
Alessandro Cosentino

71
สิ่งนี้จะทำงานได้ใน Internet Explorer แต่เฉพาะรุ่น 10 ( caniuse.com/xhr2 )
Tyler

18
สวัสดีฉันขอขอบคุณ PHP เป็นภาษาที่คุณเลือก ... แต่ฉันสงสัยว่าถ้าคุณรู้ว่ามันใช้งานได้ใน ASP.NET MVC หรือไม่? ฉันเป็นนักพัฒนา. NET และฉันพยายามใช้ตัวอย่างง่ายๆของคุณเพื่อทำการอัปโหลดไฟล์ AJAX แต่ฝั่งเซิร์ฟเวอร์ฉันไม่ได้รับไฟล์ที่โพสต์ผ่าน AJAX ฉันใช้ Chrome ล่าสุด
Shumii

25
มันเป็นFormDataที่ทำทุกสิ่งมหัศจรรย์ที่นี่ อย่าลืมตรวจสอบเอกสารเหล่านี้ซึ่งครอบคลุมคำถามทั้งหมดของคุณเกี่ยวกับไฟล์และฟิลด์ต่างๆ
เป็นตัวเป็นตน

4
เพื่อให้คนอื่นไม่ได้ใช้เวลาหลายชั่วโมง ... name="file"สิ่งที่สำคัญมากใน<input>แท็กไฟล์ถ้าคุณจะใช้ข้อมูลใน PHP (และที่อื่น ๆ ) ฉันสร้างรูปแบบไดนามิกโดยใช้ javascript ดังนั้นฉันไม่ต้องการแอตทริบิวต์ชื่อ แต่พบว่าวิธีที่ยากที่สุดที่คุณต้องการในการดึงข้อมูลเซิร์ฟเวอร์ฝั่งข้อมูล
Kivak Wolf

273

การอัพเดต 2019: ยังคงขึ้นอยู่กับเบราว์เซอร์ที่คุณใช้ตามกลุ่มประชากร

สิ่งสำคัญที่ต้องเข้าใจด้วย "ใหม่" HTML5 fileAPI คือว่ามันไม่ได้รับการสนับสนุนจน IE 10 หากตลาดเฉพาะที่คุณต้องการมีแนวโน้มสูงกว่าค่าเฉลี่ยของ Windows รุ่นเก่าคุณอาจไม่สามารถเข้าถึงได้

ในปี 2560 เบราว์เซอร์ประมาณ 5% เป็นหนึ่งใน IE 6, 7, 8 หรือ 9 ถ้าคุณมุ่งสู่ บริษัท ใหญ่ ๆ (เช่นนี่คือเครื่องมือ B2B หรือสิ่งที่คุณกำลังส่งเพื่อการฝึกอบรม) ตัวเลขนั้นสามารถพุ่งสูงขึ้นได้ . ในปี 2559 ฉันจัดการกับ บริษัท ที่ใช้ IE8 บนเครื่องของพวกเขามากกว่า 60%

มันเป็นปี 2019 ในการแก้ไขนี้เกือบ 11 ปีหลังจากคำตอบแรกของฉัน IE9 และล่างมีทั่วโลกรอบเครื่องหมาย 1% แต่ยังคงมีกลุ่มของการใช้งานที่สูงขึ้น

ที่สำคัญใช้เวลาออกไปจากนี้ -whatever feature- คือการตรวจสอบสิ่งที่เบราว์เซอร์ของคุณผู้ใช้สามารถใช้ หากคุณไม่ทำคุณจะได้เรียนรู้บทเรียนที่รวดเร็วและเจ็บปวดในเหตุที่ "ใช้งานได้สำหรับฉัน" ไม่ดีพอในการส่งมอบให้ลูกค้า caniuseเป็นเครื่องมือที่มีประโยชน์ แต่โปรดทราบว่าพวกเขาจะได้รับข้อมูลประชากรจากที่ใด พวกเขาอาจไม่สอดคล้องกับคุณ สิ่งนี้ไม่เคยเป็นจริงกว่าสภาพแวดล้อมขององค์กร

คำตอบของฉันจากปี 2008 มีดังนี้


อย่างไรก็ตามมีวิธีการอัพโหลดไฟล์ที่ไม่ใช่ของ JS คุณสามารถสร้าง iframe บนหน้า (ที่คุณซ่อนด้วย CSS) จากนั้นกำหนดเป้าหมายแบบฟอร์มของคุณเพื่อโพสต์ไปที่ iframe หน้าหลักไม่จำเป็นต้องย้าย

มันเป็นโพสต์ "ของจริง" ดังนั้นมันจึงไม่โต้ตอบทั้งหมด หากคุณต้องการสถานะคุณต้องการบางสิ่งที่ฝั่งเซิร์ฟเวอร์ในการประมวลผล สิ่งนี้จะแตกต่างกันไปขึ้นอยู่กับเซิร์ฟเวอร์ของคุณ ASP.NETมีกลไกที่ดีกว่า PHP ธรรมดาล้มเหลว แต่คุณสามารถใช้การดัดแปลงPerlหรือ Apache เพื่อหลีกเลี่ยงมัน

หากคุณต้องการอัปโหลดไฟล์หลาย ๆ ไฟล์วิธีที่ดีที่สุดคือทำทีละไฟล์ โพสต์รูปแบบแรกไปยัง iframe ตรวจสอบความคืบหน้าโดยใช้ด้านบนและเมื่อเสร็จแล้วให้โพสต์รูปแบบที่สองไปยัง iframe และอื่น ๆ

หรือใช้โซลูชัน Java / Flash พวกเขายืดหยุ่นได้มากขึ้นในสิ่งที่พวกเขาสามารถทำกับโพสต์ของพวกเขา ...


142
สำหรับเร็กคอร์ดตอนนี้เป็นไปได้ที่จะทำการอัปโหลดไฟล์ AJAX ล้วนๆหากเบราว์เซอร์รองรับ File API - developer.mozilla.org/en/using_files_from_web_applications
meleyal

โซลูชัน iframe นั้นค่อนข้างง่ายและใช้งานได้ง่าย
Matthew Lock

นี่เป็นคำตอบที่ค่อนข้างเก่า แต่มันก็เป็นความเข้าใจผิดเล็กน้อย IE ได้รับการสนับสนุน XHR ค่อนข้างไกลเท่ากับ IE7 และสนับสนุนผ่าน ActiveX ไกลเท่า IE5 w3schools.com/ajax/ajax_xmlhttprequest_create.asp วิธีปฏิบัติในการทำสิ่งนี้คือการกำหนดเป้าหมายไปที่ส่วนประกอบแฟลช (คลื่นกระแทก) หรือการเปิดตัวควบคุม Flash / ActiveX (Silverlight) หากคุณสามารถสร้างคำขอและจัดการการตอบสนองผ่านทางจาวาสคริปต์ก็เป็นอาแจ็กซ์ .. แม้ว่าจะบอกว่าอาแจ็กซ์มีความหมายเหมือนกันกับ xhr แต่มันไม่ได้อธิบายถึงกลไก / ส่วนประกอบที่ขีดเส้นใต้ที่ให้ / แลกเปลี่ยนอัตรา
Brett Caswell

4
@BrettCaswell ฉันไม่ได้บอกว่า AJAX / XHR เป็นไปไม่ได้ แต่มันเป็นไปไม่ได้ที่จะโพสต์ไฟล์กับพวกเขาในแบบเก่า - แต่ตลอดไป - เวอร์ชันของ IE นั่นคือและยังคงเป็นจริงอย่างสมบูรณ์
Oli

นี่ไม่ใช่วิธีนี้เป็นความเห็นของ UX - ตรวจสอบความถูกต้อง
Nimjox

112

ฉันแนะนำให้ใช้ปลั๊กอินFine Uploaderเพื่อจุดประสงค์นี้ JavaScriptรหัสของคุณจะเป็น:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});

มันใช้ JSON - ดังนั้นสำหรับ PHP เวอร์ชันเก่ามันจะใช้ไม่ได้
Lorenzo Manucci

ดูเหมือนว่าจะสะอาดกว่าการอัปโหลดไฟล์ Ajax ซึ่งฉันต้องใส่โค้ดขนาดใหญ่เพื่อใช้สิ่งที่น่ารังเกียจ
ripper234

URL ที่ใหม่กว่าสำหรับรุ่น 2 คือvalums-file-uploader.github.com/file-uploader
Simon East

35
"ปลั๊กอินนี้เปิดมาจาก GNU GPL 2 หรือใหม่กว่าและ GNU LGPL 2 หรือใหม่กว่า" ดังนั้นตราบใดที่คุณไม่แจกจ่ายสำเนาหรือรุ่นดัดแปลงคุณไม่จำเป็นต้องเปิดโครงการของคุณ
Trantor Liu

ฉันพลาดอะไรไปรึเปล่า? ห้องสมุดนี้ดูเหมือนจะไม่ใช้ jQuery อีกต่อไปดังนั้นจึงไม่สนับสนุนไวยากรณ์จากคำตอบใช่ไหม
James McCormack

102

หมายเหตุ: คำตอบนี้ล้าสมัยขณะนี้สามารถอัปโหลดไฟล์โดยใช้ XHR


คุณไม่สามารถอัปโหลดไฟล์โดยใช้XMLHttpRequest (Ajax) คุณสามารถจำลองเอฟเฟกต์โดยใช้ iframe หรือ Flash ปลั๊กอินฟอร์ม jQuery ที่ยอดเยี่ยมที่โพสต์ไฟล์ของคุณผ่าน iframe เพื่อให้ได้ผล


1
ใช่คุณสามารถโพสต์ไปที่ iframe และจับไฟล์ที่นั่น ฉันมีประสบการณ์ที่ จำกัด ในเรื่องนี้ดังนั้นฉันจึงไม่สามารถออกความเห็นได้
Mattias

15
ข้อสังเกตเล็ก ๆ : ใน Chrome และ firefox เวอร์ชันล่าสุดเป็นไปได้stackoverflow.com/questions/4856917/…
Alleo

ไม่รองรับใน IE9 และน้อยกว่า
Radmation

96

ปิดรับผู้อ่านในอนาคต

การอัพโหลดไฟล์แบบอะซิงโครนัส

ด้วย HTML5

คุณสามารถอัปโหลดไฟล์ด้วย jQueryโดยใช้$.ajax()วิธีนี้หากรองรับ FormDataและFile API (ทั้งคุณสมบัติ HTML5)

คุณยังสามารถส่งไฟล์โดยไม่ใช้ FormDataแต่วิธีใดวิธีหนึ่งที่ File API จะต้องมีอยู่ในการประมวลผลไฟล์ในลักษณะที่สามารถส่งด้วยXMLHttpRequest (Ajax)

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
  processData: false,
  contentType: false                    // Using FormData, no need to process data.
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

สำหรับตัวอย่าง JavaScript ที่รวดเร็วและบริสุทธิ์ ( ไม่มี jQuery ) โปรดดู "การส่งไฟล์โดยใช้ออบเจ็กต์ FormData "

รั้งท้าย

เมื่อ HTML5 ไม่ได้รับการสนับสนุน (ไม่มีFile API ) โซลูชัน JavaScript บริสุทธิ์อื่นเท่านั้น (ไม่มีFlashหรือปลั๊กอินของเบราว์เซอร์อื่น ๆ ) เป็นเทคนิคiframe ที่ซ่อนอยู่ซึ่งช่วยให้เลียนแบบคำขอแบบอะซิงโครนัสโดยไม่ต้องใช้วัตถุXMLHttpRequest

ประกอบด้วยการตั้งค่า iframe เป็นเป้าหมายของฟอร์มด้วยอินพุตไฟล์ เมื่อผู้ใช้ส่งคำขอและไฟล์ถูกอัพโหลด แต่การตอบสนองจะปรากฏขึ้นภายใน iframe แทนการแสดงผลหน้าหลักอีกครั้ง การซ่อน iframe ทำให้กระบวนการทั้งหมดโปร่งใสต่อผู้ใช้และเลียนแบบคำขออะซิงโครนัส

ถ้าทำอย่างถูกต้องมันควรจะทำงานได้จริงบนเบราว์เซอร์ใด ๆ แต่ก็มีข้อควรระวังบางอย่างเป็นวิธีการได้รับการตอบสนองจาก iframe

ในกรณีนี้คุณอาจต้องการใช้โปรแกรมเสริม wrapper เช่นBifröstซึ่งใช้เทคนิค iframeแต่ยังมีjQuery Ajax transport ที่อนุญาตให้ส่งไฟล์ด้วย$.ajax()วิธีดังนี้:

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  // Set the transport to use (iframe means to use Bifröst)
  // and the expected data type (json in this case).
  dataType: 'iframe json',                                
  fileInputs: $('input[type="file"]'),  // The file inputs containing the files to send.
  data: { msg: 'Some extra data you might need.'}
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

ปลั๊กอิน

Bifröstเป็นเพียง wrapper ขนาดเล็กที่เพิ่มการสนับสนุนทางเลือกให้กับวิธี ajax ของ jQuery แต่ปลั๊กอินดังกล่าวจำนวนมากเช่นjQuery Form PluginหรือjQuery File Uploadรวมถึงสแต็กทั้งหมดจาก HTML5 ไปยัง fallbacks ที่แตกต่างกันและคุณสมบัติที่มีประโยชน์บางอย่าง ขึ้นอยู่กับความต้องการและข้อกำหนดของคุณคุณอาจต้องการพิจารณาการนำไปใช้งานแบบไม่ใช้งานหรือปลั๊กอินตัวใดตัวหนึ่ง


3
สิ่งหนึ่งที่จะต้องทราบอยู่บนพื้นฐานของเอกสาร: contentType: falseคุณควรส่ง เมื่อฉันไม่ได้ส่งโครเมี่ยมประเภทเนื้อหาแบบฟอร์มนั้นไม่ถูกต้องโดย jQuery
เถ้า

คำตอบที่ดี คำแนะนำเล็กน้อยสำหรับการปรับปรุง: ลบส่วนของรหัสที่ไม่เกี่ยวข้องกับคำตอบตัวอย่างเช่น.done()และการ.fail()เรียกกลับ นอกจากนี้ตัวอย่างที่ไม่มีการใช้งานFormDataและรายการโปร / ข้อเสียนั้นยอดเยี่ยม
Zero3

ฉันได้รับข้อผิดพลาดนี้:TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
candlejack

85

ปลั๊กอิน jQuery การอัปโหลดไฟล์ AJAXนี้อัปโหลดไฟล์ที่ต้องการและผ่านการตอบกลับไปยังการโทรกลับไม่มีอะไรอื่น

  • มันไม่ได้ขึ้นอยู่กับ HTML ที่เฉพาะเจาะจงเพียงแค่ให้มัน <input type="file">
  • ไม่ต้องการให้เซิร์ฟเวอร์ของคุณตอบกลับโดยเฉพาะ
  • ไม่สำคัญว่าคุณจะใช้ไฟล์กี่ไฟล์หรืออยู่ที่ไหนในหน้า

- ใช้เพียงเล็กน้อย -

$('#one-specific-file').ajaxfileupload({
  'action': '/upload.php'
});

- หรือมาก -

$('input[type="file"]').ajaxfileupload({
  'action': '/upload.php',
  'params': {
    'extra': 'info'
  },
  'onComplete': function(response) {
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
  },
  'onStart': function() {
    if(weWantedTo) return false; // cancels upload
  },
  'onCancel': function() {
    console.log('no file selected');
  }
});

1
@ user840250 jQuery 1.9.1 หรือไม่
Jordan Feldstein

62

ฉันใช้สคริปต์ด้านล่างเพื่ออัปโหลดภาพที่ทำงานได้ดี

HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

JavaScript

jQuery('document').ready(function(){
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }
    input.addEventListener("change", function (evt) {
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) {
                        //showUploadedItem(e.target.result, file.fileName);
                    };
                    reader.readAsDataURL(file);
                }

                if (formdata) {
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                }

                if (formdata) {
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) {
                         jQuery('div#response').html("Successfully uploaded");
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }
        }

    }, false);
});

คำอธิบาย

ฉันใช้การตอบสนองdivเพื่อแสดงภาพเคลื่อนไหวที่อัปโหลดและการตอบสนองหลังจากอัพโหลดเสร็จแล้ว

ส่วนที่ดีที่สุดคือคุณสามารถส่งข้อมูลเพิ่มเติมเช่นรหัสและ ฯลฯ พร้อมไฟล์เมื่อคุณใช้สคริปต์นี้ ฉันได้พูดถึงมันextra-dataในสคริปต์

ในระดับ PHP สิ่งนี้จะทำงานเหมือนการอัพโหลดไฟล์ปกติ สามารถดึงข้อมูลพิเศษเป็น$_POSTข้อมูลได้

ที่นี่คุณไม่ได้ใช้ปลั๊กอินและเนื้อหา คุณสามารถเปลี่ยนรหัสได้ตามที่คุณต้องการ คุณไม่ได้เขียนโค้ดที่นี่ นี่คือฟังก์ชั่นหลักของการอัปโหลดไฟล์ jQuery Javascript จริงๆแล้ว


5
-1 สำหรับการใช้ jQuery และไม่ได้ใช้มันเป็นเครื่องมือเลือกและตัวจัดการเหตุการณ์ addEventListenerไม่ใช่ cross-browser
ทำเครื่องหมาย

3
เพราะมันไม่มีประโยชน์ที่จะเพิ่มคำตอบแยกต่างหากซึ่งส่วนใหญ่จะอิงจากคำตอบนี้โดยมีการเปลี่ยนแปลงเพียงเล็กน้อย แต่คำตอบนี้ควรได้รับการแก้ไข
ทำเครื่องหมาย

2
@RainFromHeaven ได้โปรดคุณสามารถแก้ไขคำตอบได้ไหม? ฉันไม่รู้วิธีใช้ข้ามเบราว์เซอร์
Thiago Negri

2
ยังคงไม่ทำงานใน IE 9 และลดลง ผู้ใช้จำนวนมากยังคงใช้ IE เวอร์ชันเหล่านั้น
Pierre

1
ใครช่วยกรุณาอธิบายว่าสิ่งนี้สามารถทำงานใน asp.net ได้อย่างไร? ฉันจะใช้วิธีเว็บหรือไม่ ถ้าใช่มันจะเป็นอย่างไร
SamuraiJack

49

คุณสามารถทำได้ใน JavaScript อย่างง่ายดาย นี่เป็นตัวอย่างจากโครงการปัจจุบันของฉัน:

var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
    var percent = (e.position/ e.totalSize);
    // Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
    if(this.readyState === 4) {
        // Handle file upload complete
    }
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);

3
@ แกรี่: ขออภัยฉันควรโพสต์บิตนั้นด้วย ฉันเพิ่งใช้ฟังก์ชันการลากและวางใหม่ใน HTML5 คุณสามารถหาตัวอย่างได้ที่นี่: html5demos.com/file-api#view-source - เพียงคลิก "ดูแหล่งที่มา" หลักภายในondropกิจกรรมที่คุณสามารถทำได้var file = e.dataTransfer.files[0]
mpen

บางทีคำถามได้รับการแก้ไขตั้งแต่ แต่บางคนในการอภิปรายลองฉันเปิดคิดว่าคำตอบวานิลลา JS ปิดหัวข้อถ้า OP ขอ jQuery ทางออก (ให้มีอยู่) และคำตอบดังกล่าวเป็นคำถามที่แยกต่างหาก
Andy

4
@ Andy ฉันไม่เห็นด้วยและดูเหมือนว่าคนอื่น ๆ 34 คนก็ทำเช่นกัน หากคุณสามารถใช้ jQuery คุณสามารถใช้ JavaScript ได้อย่างแน่นอน ไม่ว่าในกรณีใดนี่เป็นเว็บไซต์ชุมชน - ไม่ใช่แค่ OP ที่ฉันพยายามช่วยเหลือที่นี่ ทุกคนมีอิสระที่จะเลือก / ใช้คำตอบที่พวกเขาชอบที่สุด บางคนแค่มุ่งสู่ jQuery เพราะพวกเขาคิดว่ามันจะง่ายขึ้น / น้อยลงในบรรทัดของรหัสเมื่อจริง ๆ แล้วพวกเขาไม่ต้องการค่าใช้จ่ายของห้องสมุดเพิ่มเติมเลย
mpen

47

คุณสามารถอัปโหลดเพียงกับ .ajax()jQuery

HTML:

<form id="upload-form">
    <div>
        <label for="file">File:</label>
        <input type="file" id="file" name="file" />
        <progress class="progress" value="0" max="100"></progress>
    </div>
    <hr />
    <input type="submit" value="Submit" />
</form>

CSS

.progress { display: none; }

javascript:

$(document).ready(function(ev) {
    $("#upload-form").on('submit', (function(ev) {
        ev.preventDefault();
        $.ajax({
            xhr: function() {
                var progress = $('.progress'),
                    xhr = $.ajaxSettings.xhr();

                progress.show();

                xhr.upload.onprogress = function(ev) {
                    if (ev.lengthComputable) {
                        var percentComplete = parseInt((ev.loaded / ev.total) * 100);
                        progress.val(percentComplete);
                        if (percentComplete === 100) {
                            progress.hide().val(0);
                        }
                    }
                };

                return xhr;
            },
            url: 'upload.php',
            type: 'POST',
            data: new FormData(this),
            contentType: false,
            cache: false,
            processData: false,
            success: function(data, status, xhr) {
                // ...
            },
            error: function(xhr, status, error) {
                // ...
            }
       });
    }));
});

1
@ RaydenBlack jQuery เท่านั้น
Zayn Ali

จะรับความคืบหน้าในการอัปโหลดได้อย่างไร
Ali Sherafat

44

วิธีที่ง่ายที่สุดและแข็งแกร่งที่สุดที่ฉันเคยทำในอดีตคือการกำหนดเป้าหมายแท็ก iFrame ที่ซ่อนอยู่ในแบบฟอร์มของคุณ - จากนั้นจะส่งภายใน iframe โดยไม่ต้องโหลดหน้าซ้ำ

นั่นคือถ้าคุณไม่ต้องการใช้ปลั๊กอิน JavaScript หรือรูปแบบอื่น ๆ ของ "เวทย์มนตร์" นอกเหนือจาก HTML แน่นอนว่าคุณสามารถรวมสิ่งนี้กับ JavaScript หรือสิ่งที่คุณมี ...

<form target="iframe" action="" method="post" enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

<iframe name="iframe" id="iframe" style="display:none" ></iframe>

คุณยังสามารถอ่านเนื้อหาของ iframe onLoadเพื่อหาข้อผิดพลาดของเซิร์ฟเวอร์หรือการตอบสนองต่อความสำเร็จแล้วส่งออกไปยังผู้ใช้

Chrome, iFrames และ onLoad

- หมายเหตุ - คุณต้องอ่านต่อไปหากคุณสนใจที่จะตั้งค่า UI blocker เมื่อทำการอัพโหลด / ดาวน์โหลด

ปัจจุบัน Chrome ไม่เรียกใช้งานกิจกรรม onLoad สำหรับ iframe เมื่อใช้เพื่อถ่ายโอนไฟล์ Firefox, IE และ Edge ทั้งหมดใช้ไฟเหตุการณ์ onload สำหรับการถ่ายโอนไฟล์

ทางออกเดียวที่ฉันพบว่าใช้ได้กับ Chrome คือการใช้คุกกี้

ในการทำเช่นนั้นโดยทั่วไปเมื่อเริ่มอัพโหลด / ดาวน์โหลด:

  • [ฝั่งไคลเอ็นต์] เริ่มต้นช่วงเวลาเพื่อค้นหาการมีอยู่ของคุกกี้
  • [ฝั่งเซิร์ฟเวอร์] ทำทุกสิ่งที่คุณต้องการด้วยข้อมูลไฟล์
  • [ฝั่งเซิร์ฟเวอร์] ตั้งค่าคุกกี้สำหรับช่วงเวลาฝั่งไคลเอ็นต์
  • [ฝั่งไคลเอ็นต์] ช่วงเวลาที่เห็นคุกกี้และใช้มันเหมือนเหตุการณ์ onLoad ตัวอย่างเช่นคุณสามารถเริ่ม UI blocker และจากนั้นโหลด (หรือเมื่อทำคุกกี้) คุณจะลบ UI blocker

การใช้คุกกี้สำหรับสิ่งนี้น่าเกลียด แต่ใช้งานได้

ฉันสร้างปลั๊กอิน jQuery เพื่อจัดการปัญหานี้สำหรับ Chrome เมื่อดาวน์โหลดคุณสามารถค้นหาได้ที่นี่

https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/iDownloader.js

หลักการพื้นฐานเดียวกันนี้ใช้กับการอัปโหลดเช่นกัน

ในการใช้ตัวดาวน์โหลด (รวมถึง JS อย่างชัดเจน)

 $('body').iDownloader({
     "onComplete" : function(){
          $('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
     }
 });

 $('somebuttion').click( function(){
      $('#uiBlocker').css('display', 'block'); //block the UI
      $('body').iDownloader('download', 'htttp://example.com/location/of/download');
 });

และที่ฝั่งเซิร์ฟเวอร์ก่อนที่จะถ่ายโอนข้อมูลไฟล์ให้สร้างคุกกี้

 setcookie('iDownloader', true, time() + 30, "/");

ปลั๊กอินจะเห็นคุกกี้แล้วเปิดใช้งานการonCompleteเรียกกลับ


3
ฉันรักมัน. หากมีใครบางคนเท่านั้นที่สามารถพูดถึงปัญหาที่อาจเกิดขึ้นกับโซลูชั่นที่ยอดเยี่ยมนี้ ฉันไม่เข้าใจจริงๆว่าทำไมผู้คนถึงโต้เถียงกันและใช้ไลบรารีและปลั๊กอินที่ clunky เหล่านี้เมื่อมีวิธีแก้ปัญหา
Yevgeniy Afanasyev

1
ฉันเดาว่าเหตุผลที่จะแสดงข้อมูลความคืบหน้าขณะทำการอัพโหลด
Prakhar Mishra

32

วิธีแก้ปัญหาที่ฉันพบคือการให้<form>เป้าหมายเป็น iFrame ที่ซ่อนอยู่ จากนั้น iFrame สามารถเรียกใช้ JS เพื่อแสดงต่อผู้ใช้ว่าเสร็จสมบูรณ์แล้ว (ขณะโหลดหน้าเว็บ)


1
ฉันสนใจคำตอบนี้คุณมีตัวอย่างที่คุณสามารถลิงค์ไปได้หรือไม่?
lfender6445

32

ฉันได้เขียนขึ้นในสภาพแวดล้อมทางรถไฟ มันเป็นแค่ประมาณห้าบรรทัดของ JavaScript ถ้าคุณใช้ปลั๊กอินรูปแบบน้ำหนักเบา jQuery

ความท้าทายในการทำให้การอัปโหลด AJAX ทำงานได้เป็นมาตรฐานremote_form_forไม่เข้าใจการส่งแบบฟอร์มหลายส่วน มันจะไม่ส่งไฟล์ข้อมูล Rails กลับมาพร้อมกับคำขอ AJAX

นั่นคือสิ่งที่ปลั๊กอินรูปแบบ jQuery เข้ามาเล่น

นี่คือรหัส Rails สำหรับมัน:

<% remote_form_for(:image_form, 
                   :url => { :controller => "blogs", :action => :create_asset }, 
                   :html => { :method => :post, 
                              :id => 'uploadForm', :multipart => true }) 
                                                                        do |f| %>
 Upload a file: <%= f.file_field :uploaded_data %>
<% end %>

นี่คือ JavaScript ที่เกี่ยวข้อง:

$('#uploadForm input').change(function(){
 $(this).parent().ajaxSubmit({
  beforeSubmit: function(a,f,o) {
   o.dataType = 'json';
  },
  complete: function(XMLHttpRequest, textStatus) {
   // XMLHttpRequest.responseText will contain the URL of the uploaded image.
   // Put it in an image element you create, or do with it what you will.
   // For example, if you have an image elemtn with id "my_image", then
   //  $('#my_image').attr('src', XMLHttpRequest.responseText);
   // Will set that image tag to display the uploaded image.
  },
 });
});

และนี่คือแอคชั่นควบคุม Rails, วนิลาสวย:

 @image = Image.new(params[:image_form])
 @image.save
 render :text => @image.public_filename

ฉันใช้สิ่งนี้ในช่วงสองสามสัปดาห์ที่ผ่านมากับ Bloggity และใช้งานได้เหมือนแชมป์


31

Ajax Uploader ธรรมดาเป็นอีกตัวเลือกหนึ่ง:

https://github.com/LPology/Simple-Ajax-Uploader

  • Cross-browser - ทำงานใน IE7 +, Firefox, Chrome, Safari, Opera
  • รองรับการอัปโหลดหลายรายการพร้อมกัน - แม้ในเบราว์เซอร์ที่ไม่ใช่ HTML5
  • ไม่มีแฟลชหรือ CSS ภายนอก - ไฟล์ Javascript 5Kb เพียงไฟล์เดียว
  • การสนับสนุนในตัวสำหรับแถบความคืบหน้าข้ามเบราว์เซอร์อย่างสมบูรณ์ (โดยใช้ส่วนขยาย APC ของ PHP)
  • ยืดหยุ่นและปรับแต่งได้สูง - ใช้องค์ประกอบใด ๆ เป็นปุ่มอัปโหลดสไตล์ตัวบ่งชี้ความคืบหน้าของคุณเอง
  • ไม่ต้องใช้แบบฟอร์มเพียงระบุองค์ประกอบที่จะใช้เป็นปุ่มอัปโหลด
  • สิทธิ์การใช้งาน MIT - ฟรีเพื่อใช้ในโครงการเชิงพาณิชย์

ตัวอย่างการใช้งาน:

var uploader = new ss.SimpleUpload({
    button: $('#uploadBtn'), // upload button
    url: '/uploadhandler', // URL of server-side upload handler
    name: 'userfile', // parameter name of the uploaded file
    onSubmit: function() {
        this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
    },
    onComplete: function(file, response) {
        // do whatever after upload is finished
    }
});

2
นี่ดูเหมือนจะเป็นสัญญาที่ดีที่สุดจนถึงตอนนี้คุณมีฉันอยู่IE7+! ลองใช้เลย ขอบคุณ
Pierre

25

jQuery Uploadifyเป็นอีกหนึ่งปลั๊กอินที่ดีที่ฉันเคยใช้ก่อนอัปโหลดไฟล์ รหัส JavaScript นั้นง่ายเหมือนดังต่อไปนี้: code อย่างไรก็ตามเวอร์ชันใหม่ไม่สามารถใช้งานได้ใน Internet Explorer

$('#file_upload').uploadify({
    'swf': '/public/js/uploadify.swf',
    'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(),
    'cancelImg': '/public/images/uploadify-cancel.png',
    'multi': true,
    'onQueueComplete': function (queueData) {
        // ...
    },
    'onUploadStart': function (file) {
        // ...
    }
});

ฉันทำการค้นหาจำนวนมากและฉันมาที่โซลูชันอื่นสำหรับการอัปโหลดไฟล์โดยไม่มีปลั๊กอินและใช้กับ ajax เท่านั้น การแก้ปัญหาดังต่อไปนี้:

$(document).ready(function () {
    $('#btn_Upload').live('click', AjaxFileUpload);
});

function AjaxFileUpload() {
    var fileInput = document.getElementById("#Uploader");
    var file = fileInput.files[0];
    var fd = new FormData();
    fd.append("files", file);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'Uploader.ashx');
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
             alert('success');
        }
        else if (uploadResult == 'success')
            alert('error');
    };
    xhr.send(fd);
}

2
Uploadify ตายไปแล้วหลายปี ไม่ได้รับการสนับสนุนหรือดูแลรักษาอีกต่อไป
เรย์นิโคลัส

24

นี่เป็นอีกวิธีในการอัปโหลดไฟล์ ( ไม่มีปลั๊กอิน )

การใช้JavascriptและAJAXแบบง่าย(พร้อมแถบความคืบหน้า)

ส่วน HTML

<form id="upload_form" enctype="multipart/form-data" method="post">
    <input type="file" name="file1" id="file1"><br>
    <input type="button" value="Upload File" onclick="uploadFile()">
    <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
    <h3 id="status"></h3>
    <p id="loaded_n_total"></p>
</form>

ส่วนของ JS

function _(el){
    return document.getElementById(el);
}
function uploadFile(){
    var file = _("file1").files[0];
    // alert(file.name+" | "+file.size+" | "+file.type);
    var formdata = new FormData();
    formdata.append("file1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}
function progressHandler(event){
    _("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
    _("status").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
}
function errorHandler(event){
    _("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
    _("status").innerHTML = "Upload Aborted";
}

ส่วน PHP

<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
}
if(move_uploaded_file($fileTmpLoc, "test_uploads/$fileName")){ // assuming the directory name 'test_uploads'
    echo "$fileName upload is complete";
} else {
    echo "move_uploaded_file function failed";
}
?>

นี่คือแอปพลิเคชันตัวอย่าง


19
var formData=new FormData();
formData.append("fieldname","value");
formData.append("image",$('[name="filename"]')[0].files[0]);

$.ajax({
    url:"page.php",
    data:formData,
    type: 'POST',
    dataType:"JSON",
    cache: false,
    contentType: false,
    processData: false,
    success:function(data){ }
});

คุณสามารถใช้ข้อมูลแบบฟอร์มเพื่อโพสต์ค่าทั้งหมดของคุณรวมถึงรูปภาพ


6
หมายเหตุ: cache: falseซ้ำซ้อนกับการPOSTร้องขออย่างที่POST ไม่เคยแคช
Gone Coding

@Vivek Aasaithambi ฉันได้รับข้อผิดพลาดนี้:TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
candlejack

15

ในการอัปโหลดไฟล์แบบอะซิงโครนัสกับ Jquery ใช้ขั้นตอนด้านล่าง:

ขั้นตอนที่ 1ในโปรเจคของคุณให้เปิด Nuget manager และเพิ่มแพ็คเกจ (ไฟล์ jquery fileupload (เฉพาะคุณเท่านั้นที่จำเป็นต้องเขียนลงในช่องค้นหามันจะเกิดขึ้นและติดตั้ง)) URL: https://github.com/blueimp/jQuery-File- ที่อัพโหลด

ขั้นตอนที่ 2เพิ่มสคริปต์ด้านล่างในไฟล์ HTML ซึ่งเพิ่มไว้ในโครงการแล้วโดยเรียกใช้แพ็คเกจด้านบน:

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

ขั้นตอนที่ 3 เขียนควบคุมการอัปโหลดไฟล์ตามรหัสด้านล่าง:

<input id="upload" name="upload" type="file" />

ขั้นตอนที่ 4 เขียนวิธี js เป็น uploadFile ดังนี้

 function uploadFile(element) {

            $(element).fileupload({

                dataType: 'json',
                url: '../DocumentUpload/upload',
                autoUpload: true,
                add: function (e, data) {           
                  // write code for implementing, while selecting a file. 
                  // data represents the file data. 
                  //below code triggers the action in mvc controller
                  data.formData =
                                    {
                                     files: data.files[0]
                                    };
                  data.submit();
                },
                done: function (e, data) {          
                   // after file uploaded
                },
                progress: function (e, data) {

                   // progress
                },
                fail: function (e, data) {

                   //fail operation
                },
                stop: function () {

                  code for cancel operation
                }
            });

        };

ขั้นตอนที่ 5ในการเรียกใช้ฟังก์ชั่นไฟล์องค์ประกอบพร้อมฟังก์ชั่นการอัพโหลดเพื่อเริ่มต้นกระบวนการดังต่อไปนี้:

$(document).ready(function()
{
    uploadFile($('#upload'));

});

ขั้นตอนที่ 6เขียนคอนโทรลเลอร์ MVC และการดำเนินการตามด้านล่าง:

public class DocumentUploadController : Controller
    {       

        [System.Web.Mvc.HttpPost]
        public JsonResult upload(ICollection<HttpPostedFileBase> files)
        {
            bool result = false;

            if (files != null || files.Count > 0)
            {
                try
                {
                    foreach (HttpPostedFileBase file in files)
                    {
                        if (file.ContentLength == 0)
                            throw new Exception("Zero length file!");                       
                        else 
                            //code for saving a file

                    }
                }
                catch (Exception)
                {
                    result = false;
                }
            }


            return new JsonResult()
                {
                    Data=result
                };


        }

    }

14

วิธีการที่ทันสมัยโดยไม่มี Jqueryคือการใช้วัตถุFileList ที่คุณได้รับกลับมา<input type="file">เมื่อผู้ใช้เลือกไฟล์แล้วใช้Fetchเพื่อโพสต์ FileList ที่ล้อมรอบวัตถุFormData

// The input DOM element // <input type="file">
const inputElement = document.querySelector('input[type=file]');

// Listen for a file submit from user
inputElement.addEventListener('change', () => {
    const data = new FormData();
    data.append('file', inputElement.files[0]);
    data.append('imageName', 'flower');

    // You can then post it to your server.
    // Fetch can accept an object of type FormData on its  body
    fetch('/uploadImage', {
        method: 'POST',
        body: data
    });
});

ไม่รองรับ IE
Marco Demaio

11

คุณสามารถดูวิธีแก้ปัญหาที่มีการสาธิตการทำงานที่นี่ที่ช่วยให้คุณสามารถดูตัวอย่างและส่งไฟล์แบบฟอร์มไปยังเซิร์ฟเวอร์ สำหรับกรณีของคุณคุณต้องใช้Ajaxเพื่ออำนวยความสะดวกในการอัปโหลดไฟล์ไปยังเซิร์ฟเวอร์:

<from action="" id="formContent" method="post" enctype="multipart/form-data">
    <span>File</span>
    <input type="file" id="file" name="file" size="10"/>
    <input id="uploadbutton" type="button" value="Upload"/>
</form>

ข้อมูลที่ถูกส่งเป็นรูปแบบข้อมูล ใน jQuery ของคุณให้ใช้ฟังก์ชั่นส่งแบบฟอร์มแทนการคลิกปุ่มเพื่อส่งไฟล์แบบฟอร์มที่แสดงด้านล่าง

$(document).ready(function () {
   $("#formContent").submit(function(e){

     e.preventDefault();
     var formdata = new FormData(this);

 $.ajax({
     url: "ajax_upload_image.php",
     type: "POST",
     data: formdata,
     mimeTypes:"multipart/form-data",
     contentType: false,
     cache: false,
     processData: false,
     success: function(){

     alert("successfully submitted");

     });
   });
});

ดูรายละเอียดเพิ่มเติม


11

ตัวอย่าง: ถ้าคุณใช้ jQuery คุณสามารถทำได้ง่าย ๆ กับไฟล์อัพโหลด นี้เป็นปลั๊กอิน jQuery ขนาดเล็กและแข็งแรงhttp://jquery.malsup.com/form/

ตัวอย่าง

var $bar   = $('.ProgressBar');
$('.Form').ajaxForm({
  dataType: 'json',

  beforeSend: function(xhr) {
    var percentVal = '0%';
    $bar.width(percentVal);
  },

  uploadProgress: function(event, position, total, percentComplete) {
    var percentVal = percentComplete + '%';
    $bar.width(percentVal)
  },

  success: function(response) {
    // Response
  }
});

ฉันหวังว่ามันจะเป็นประโยชน์



9

แปลงไฟล์เป็น base64 ใช้ | HTML5 ของreadAsDataURL ()หรือบางเข้ารหัส base64 เล่นซอที่นี่

var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById("base64textarea").value = btoa(binaryString);
        };

        reader.readAsBinaryString(file);

จากนั้นเรียกคืน:

window.open("data:application/octet-stream;base64," + base64);

9

คุณสามารถส่งพารามิเตอร์เพิ่มเติมพร้อมกับชื่อไฟล์ในการอัปโหลดแบบอะซิงโครนัสโดยใช้ XMLHttpRequest (โดยไม่ต้องใช้แฟลชและการพึ่งพา iframe) ผนวกค่าพารามิเตอร์เพิ่มเติมด้วย FormData และส่งคำขออัปโหลด


var formData = new FormData();
formData.append('parameter1', 'value1');
formData.append('parameter2', 'value2'); 
formData.append('file', $('input[type=file]')[0].files[0]);

$.ajax({
    url: 'post back url',
    data: formData,
// other attributes of AJAX
});

นอกจากนี้การอัปโหลดไฟล์ Syncfusion JavaScript UI ยังมีวิธีแก้ปัญหาสำหรับสถานการณ์นี้โดยใช้อาร์กิวเมนต์ของเหตุการณ์ คุณสามารถค้นหาเอกสารได้ที่นี่และรายละเอียดเพิ่มเติมเกี่ยวกับการควบคุมนี้ที่นี่ป้อนคำอธิบายลิงก์ที่นี่


8

ค้นหาการจัดการกระบวนการอัปโหลดไฟล์แบบอะซิงโครนัสที่นี่: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

ตัวอย่างจากลิงค์

<?php
if (isset($_FILES['myFile'])) {
    // Example:
    move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
    exit;
}
?><!DOCTYPE html>
<html>
<head>
    <title>dnd binary upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        function sendFile(file) {
            var uri = "/index.php";
            var xhr = new XMLHttpRequest();
            var fd = new FormData();

            xhr.open("POST", uri, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // Handle response.
                    alert(xhr.responseText); // handle response.
                }
            };
            fd.append('myFile', file);
            // Initiate a multipart/form-data upload
            xhr.send(fd);
        }

        window.onload = function() {
            var dropzone = document.getElementById("dropzone");
            dropzone.ondragover = dropzone.ondragenter = function(event) {
                event.stopPropagation();
                event.preventDefault();
            }

            dropzone.ondrop = function(event) {
                event.stopPropagation();
                event.preventDefault();

                var filesArray = event.dataTransfer.files;
                for (var i=0; i<filesArray.length; i++) {
                    sendFile(filesArray[i]);
                }
            }
        }
    </script>
</head>
<body>
    <div>
        <div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
    </div>
</body>
</html>

7

นี่คือทางออกของฉัน

<form enctype="multipart/form-data">    

    <div class="form-group">
        <label class="control-label col-md-2" for="apta_Description">Description</label>
        <div class="col-md-10">
            <input class="form-control text-box single-line" id="apta_Description" name="apta_Description" type="text" value="">
        </div>
    </div>

    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

และ js

<script>

    $(':button').click(function () {
        var formData = new FormData($('form')[0]);
        $.ajax({
            url: '@Url.Action("Save", "Home")',  
            type: 'POST',                
            success: completeHandler,
            data: formData,
            cache: false,
            contentType: false,
            processData: false
        });
    });    

    function completeHandler() {
        alert(":)");
    }    
</script>

ตัวควบคุม

[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
    [...]
}

2
คุณดูเหมือนจะผสมกรอบบางอย่างเข้ากับคำตอบของคุณ อย่างน้อยที่สุดคุณควรกล่าวถึงกรอบการทำงานที่คำตอบของคุณใช้ได้ ดีกว่ายังเอาสิ่งที่กรอบทั้งหมดและนำเสนอเพียงคำตอบสำหรับคำถามที่ถูกวาง
Zero3

2
ดังนั้นจึงมีกรอบ mvc จริง ๆ เรียกว่า "mvc" และมันใช้ไวยากรณ์ csharpish? นั่นโหดร้าย
nonchip

6

การใช้HTML5และJavaScriptการอัปโหลด async นั้นค่อนข้างง่ายฉันสร้างตรรกะการอัปโหลดพร้อมกับ html ของคุณซึ่งไม่สามารถทำงานได้อย่างเต็มที่ตามที่ต้องการ api แต่แสดงให้เห็นว่ามันทำงานอย่างไรถ้าคุณมีปลายทางที่เรียก/uploadจากรูทของเว็บไซต์ของคุณ รหัสนี้ควรจะทำงานให้คุณ:

const asyncFileUpload = () => {
  const fileInput = document.getElementById("file");
  const file = fileInput.files[0];
  const uri = "/upload";
  const xhr = new XMLHttpRequest();
  xhr.upload.onprogress = e => {
    const percentage = e.loaded / e.total;
    console.log(percentage);
  };
  xhr.onreadystatechange = e => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log("file uploaded");
    }
  };
  xhr.open("POST", uri, true);
  xhr.setRequestHeader("X-FileName", file.name);
  xhr.send(file);
}
<form>
  <span>File</span>
  <input type="file" id="file" name="file" size="10" />
  <input onclick="asyncFileUpload()" id="upload" type="button" value="Upload" />
</form>

นอกจากนี้ยังมีข้อมูลเพิ่มเติมเกี่ยวกับ XMLHttpReques:

วัตถุ XMLHttpRequest

เบราว์เซอร์ที่ทันสมัยทั้งหมดรองรับวัตถุ XMLHttpRequest วัตถุ XMLHttpRequest สามารถใช้เพื่อแลกเปลี่ยนข้อมูลกับเว็บเซิร์ฟเวอร์ที่อยู่เบื้องหลัง ซึ่งหมายความว่าเป็นไปได้ที่จะอัปเดตบางส่วนของหน้าเว็บโดยไม่ต้องโหลดซ้ำทั้งหน้า


สร้างวัตถุ XMLHttpRequest

เบราว์เซอร์ที่ทันสมัยทั้งหมด (Chrome, Firefox, IE7 +, Edge, Safari, Opera) มีวัตถุ XMLHttpRequest ในตัว

ไวยากรณ์สำหรับการสร้างวัตถุ XMLHttpRequest:

ตัวแปร = ใหม่ XMLHttpRequest ();


เข้าถึงข้ามโดเมน

เพื่อเหตุผลด้านความปลอดภัยเบราว์เซอร์ที่ทันสมัยไม่อนุญาตการเข้าถึงข้ามโดเมน

ซึ่งหมายความว่าทั้งหน้าเว็บและไฟล์ XML ที่พยายามโหลดจะต้องอยู่ในเซิร์ฟเวอร์เดียวกัน

ตัวอย่างใน W3Schools ไฟล์ XML แบบเปิดทั้งหมดที่อยู่ในโดเมน W3Schools

หากคุณต้องการใช้ตัวอย่างด้านบนบนหนึ่งในหน้าเว็บของคุณเองไฟล์ XML ที่คุณโหลดจะต้องอยู่บนเซิร์ฟเวอร์ของคุณเอง

สำหรับรายละเอียดเพิ่มเติมคุณสามารถอ่านต่อได้ที่นี่ ...


5

คุณสามารถใช้Fetch API ที่ใหม่กว่าได้ ด้วย JavaScript แบบนี้:

function uploadButtonCLicked(){
    var input = document.querySelector('input[type="file"]')

    fetch('/url', {
      method: 'POST',
      body: input.files[0]
    }).then(res => res.json())   // you can do something with response
      .catch(error => console.error('Error:', error))
      .then(response => console.log('Success:', response));
}                               

ข้อได้เปรียบ: Fetch API ได้รับการสนับสนุนโดยเบราว์เซอร์สมัยใหม่ทั้งหมดดังนั้นคุณไม่ต้องนำเข้าอะไรเลย นอกจากนี้โปรดทราบว่าการดึงข้อมูล () จะส่งกลับสัญญาซึ่งถูกจัดการโดยใช้.then(..code to handle response..)แบบอะซิงโครนัส


4

คุณสามารถอัปโหลดไฟล์หลายไฟล์แบบอะซิงโครนัสได้โดยใช้ JavaScript หรือ jQuery และไปที่โดยไม่ต้องใช้ปลั๊กอินใด ๆ นอกจากนี้คุณยังสามารถแสดงความคืบหน้าตามเวลาจริงของการอัปโหลดไฟล์ในการควบคุมความคืบหน้า ฉันเจอลิงก์ 2 ลิงค์ที่ดี -

  1. คุณสมบัติการอัปโหลดไฟล์ Mulitple ที่ใช้เว็บฟอร์ม ASP.NET ด้วยแถบความก้าวหน้า
  2. ASP.NET MVC อัปโหลดหลายไฟล์ตาม jQuery

ภาษาฝั่งเซิร์ฟเวอร์คือ C # แต่คุณสามารถทำการปรับเปลี่ยนบางอย่างเพื่อให้ทำงานกับภาษาอื่นเช่น PHP

การอัพโหลดไฟล์ ASP.NET Core MVC:

ในมุมมองสร้างการควบคุมการอัปโหลดไฟล์ใน html:

<form method="post" asp-action="Add" enctype="multipart/form-data">
    <input type="file" multiple name="mediaUpload" />
    <button type="submit">Submit</button>
</form>

ตอนนี้สร้างวิธีการกระทำในตัวควบคุมของคุณ:

[HttpPost]
public async Task<IActionResult> Add(IFormFile[] mediaUpload)
{
    //looping through all the files
    foreach (IFormFile file in mediaUpload)
    {
        //saving the files
        string path = Path.Combine(hostingEnvironment.WebRootPath, "some-folder-path"); 
        using (var stream = new FileStream(path, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }
    }
}

ตัวแปร hostingEnvironment เป็นประเภท IHostingEnvironment ซึ่งสามารถฉีดไปยังตัวควบคุมโดยใช้การฉีดพึ่งพาเช่น:

private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
    hostingEnvironment = environment;
}

คุณสามารถรวมสาระสำคัญของการแก้ปัญหาไว้ในคำตอบของคุณได้หรือไม่เพราะมันอาจไร้ประโยชน์หากเว็บไซต์ที่เชื่อมโยงมีการเปลี่ยนแปลงหรือออฟไลน์
Dima Kozhevin

4

สำหรับ PHP ให้มองหาhttps://developer.hyvor.com/php/image-upload-ajax-php-mysql

HTML

<html>
<head>
    <title>Image Upload with AJAX, PHP and MYSQL</title>
</head>
<body>
<form onsubmit="submitForm(event);">
    <input type="file" name="image" id="image-selecter" accept="image/*">
    <input type="submit" name="submit" value="Upload Image">
</form>
<div id="uploading-text" style="display:none;">Uploading...</div>
<img id="preview">
</body>
</html>

JAVASCRIPT

var previewImage = document.getElementById("preview"),  
    uploadingText = document.getElementById("uploading-text");

function submitForm(event) {
    // prevent default form submission
    event.preventDefault();
    uploadImage();
}

function uploadImage() {
    var imageSelecter = document.getElementById("image-selecter"),
        file = imageSelecter.files[0];
    if (!file) 
        return alert("Please select a file");
    // clear the previous image
    previewImage.removeAttribute("src");
    // show uploading text
    uploadingText.style.display = "block";
    // create form data and append the file
    var formData = new FormData();
    formData.append("image", file);
    // do the ajax part
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            var json = JSON.parse(this.responseText);
            if (!json || json.status !== true) 
                return uploadError(json.error);

            showImage(json.url);
        }
    }
    ajax.open("POST", "upload.php", true);
    ajax.send(formData); // send the form data
}

PHP

<?php
$host = 'localhost';
$user = 'user';
$password = 'password';
$database = 'database';
$mysqli = new mysqli($host, $user, $password, $database);


 try {
    if (empty($_FILES['image'])) {
        throw new Exception('Image file is missing');
    }
    $image = $_FILES['image'];
    // check INI error
    if ($image['error'] !== 0) {
        if ($image['error'] === 1) 
            throw new Exception('Max upload size exceeded');

        throw new Exception('Image uploading error: INI Error');
    }
    // check if the file exists
    if (!file_exists($image['tmp_name']))
        throw new Exception('Image file is missing in the server');
    $maxFileSize = 2 * 10e6; // in bytes
    if ($image['size'] > $maxFileSize)
        throw new Exception('Max size limit exceeded'); 
    // check if uploaded file is an image
    $imageData = getimagesize($image['tmp_name']);
    if (!$imageData) 
        throw new Exception('Invalid image');
    $mimeType = $imageData['mime'];
    // validate mime type
    $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
    if (!in_array($mimeType, $allowedMimeTypes)) 
        throw new Exception('Only JPEG, PNG and GIFs are allowed');

    // nice! it's a valid image
    // get file extension (ex: jpg, png) not (.jpg)
    $fileExtention = strtolower(pathinfo($image['name'] ,PATHINFO_EXTENSION));
    // create random name for your image
    $fileName = round(microtime(true)) . mt_rand() . '.' . $fileExtention; // anyfilename.jpg
    // Create the path starting from DOCUMENT ROOT of your website
    $path = '/examples/image-upload/images/' . $fileName;
    // file path in the computer - where to save it 
    $destination = $_SERVER['DOCUMENT_ROOT'] . $path;

    if (!move_uploaded_file($image['tmp_name'], $destination))
        throw new Exception('Error in moving the uploaded file');

    // create the url
    $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
    $domain = $protocol . $_SERVER['SERVER_NAME'];
    $url = $domain . $path;
    $stmt = $mysqli -> prepare('INSERT INTO image_uploads (url) VALUES (?)');
    if (
        $stmt &&
        $stmt -> bind_param('s', $url) &&
        $stmt -> execute()
    ) {
        exit(
            json_encode(
                array(
                    'status' => true,
                    'url' => $url
                )
            )
        );
    } else 
        throw new Exception('Error in saving into the database');

} catch (Exception $e) {
    exit(json_encode(
        array (
            'status' => false,
            'error' => $e -> getMessage()
        )
    ));
}

4

นอกจากนี้คุณยังสามารถพิจารณาใช้สิ่งที่ต้องการhttps://uppy.io

มันจะทำการอัปโหลดไฟล์โดยไม่ต้องออกจากหน้าเว็บและให้โบนัสเล็กน้อยเช่นการลากและวางการอัปโหลดต่อในกรณีที่เบราว์เซอร์ล่ม / เครือข่ายที่ไม่สม่ำเสมอและนำเข้าจากอินสตาแกรมเช่น เป็นโอเพ่นซอร์สและไม่พึ่งพา jQuery / React / Angular / Vue แต่สามารถใช้ได้กับมัน คำเตือน: ในฐานะผู้สร้างฉันลำเอียง;)


ลิงค์ด้านบนเสียชีวิต นี่คือ github: github.com/transloadit/uppy
Chris Charles

uppy.io สำรองข้อมูล CloudFlare + GitHub แล้วหรือยัง? ยังมีประโยชน์ที่จะมีลิงค์ repo โดยตรงเช่นกัน :)
23432
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.