फ़ाइल डाउनलोड करने के बाद प्रसंस्करण करने के लिए जावास्क्रिप्ट

पेज अद्यतन :
पेज निर्माण की तारीख :

ऑपरेशन सत्यापन वातावरण

विजुअल स्टूडियो
  • विजुअल स्टूडियो 2022
ASP.NET कोर
  • 8.0 (Razpr पृष्ठ, MVC)
वेब ब्राउज़र
  • एज 119

परिचालन का वातावरण

Visual Studio (यदि आप सर्वर प्रोग्राम भी शामिल करते हैं)
  • विजुअल स्टूडियो 2022
ASP.NET कोर (यदि इसमें सर्वर प्रोग्राम भी शामिल हैं)
  • 8.0 (Razpr पृष्ठ, MVC)
वेब ब्राउज़र
  • किनारा
  • गूगल क्रोम
  • अन्य ब्राउज़र (सभी चेक नहीं किए गए)

(* इस टिप का मुख्य भाग क्लाइंट-साइड प्रक्रिया है, इसलिए सर्वर साइड कुछ भी हो सकता है)

पहले

इन युक्तियों का मुख्य फोकस क्लाइंट प्रोग्राम (जावास्क्रिप्ट) है, और सर्वर प्रोग्राम केवल फ़ाइलों को डाउनलोड करने के लिए है। इसलिए, इससे कोई फर्क नहीं पड़ता कि सर्वर प्रोग्राम क्या है, जब तक कि यह आपको फ़ाइल डाउनलोड कर सकता है।

उपयोगकर्ताओं को सर्वर पर एक्सेस किए जाने पर फ़ाइलें डाउनलोड करने दें

श्री/सुश्री आपको अनुरोध प्राप्त होने पर फ़ाइलें डाउनलोड करने की अनुमति देता है। उस समय, हम जानबूझकर सर्वर पर एक निश्चित समय तक प्रतीक्षा करते हैं ताकि डाउनलोड के प्रारंभ और अंत को समझना आसान हो।

यहां रेजर पेज और एमवीसी के सर्वर साइड पर क्या होता है: आप इसे वेब एपीआई जैसी अन्य परियोजनाओं में लागू कर सकते हैं।

रेजर पेज : पन्ने/Index.cshtml.cs

// 省略

namespace DownloadCompleteNotifyRazorPages.Pages
{
  public class IndexModel : PageModel
  {
    // 省略

    /// <summary>時間をかけてファイルをダウンロードします。</summary>
    public async Task<IActionResult> OnGetDownload()
    {
      // ダウンロード開始と完了を明確にする目的で待機を入れる
      await Task.Delay(5000);

      // 適当にファイルを作って返す
      var fileSize = 10_000_000;
      var sb = new System.Text.StringBuilder(fileSize);
      for (int i = 0; i < fileSize; i++) sb.Append('a');
      using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));
      return File(stream.ToArray(), "text/plain", $"ダウンロード.txt");
    }
  }
}

एमवीसी: कोलटोलर/HomeController.cs

// 省略

namespace DownloadCompleteNotifyMvc.Controllers
{
  public class HomeController : Controller
  {
    // 省略

    /// <summary>時間をかけてファイルをダウンロードします。</summary>
    public async Task<IActionResult> Download()
    {
      // ダウンロード開始と完了を明確にする目的で待機を入れる
      await Task.Delay(5000);

      // 適当にファイルを作って返す
      var fileSize = 10_000_000;
      var sb = new System.Text.StringBuilder(fileSize);
      for (int i = 0; i < fileSize; i++) sb.Append('a');
      using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));
      return File(stream.ToArray(), "text/plain", $"ダウンロード.txt");
    }
  }
}

ग्राहक प्रसंस्करण

आम तौर पर, आप एक वेब ब्राउज़र में एक निर्दिष्ट URL तक पहुंचकर एक फ़ाइल डाउनलोड करते हैं। यदि आप डाउनलोड पूरा होने के बाद कुछ करना चाहते हैं, तो आप जावास्क्रिप्ट के साथ डाउनलोड चला सकते हैं।

ऐसा करने के कई तरीके हैं, लेकिन इस मामले में, हम उपयोग करेंगे , जो अतुल्यकालिक प्रसंस्करण का मूल भी XMLHttpRequest है। आप jQuery ajax फ़ंक्शन या फ़ेच API का भी उपयोग कर सकते हैं।

ahref डाउनलोड URL टैग में लिखा गया है और id जब एक सेट पर क्लिक किया download जाता है तो प्रक्रिया निष्पादित होती है।

$('#download').click(function (e) {
  console.log('ダウンロードを開始します。');
  e.preventDefault();  // href による画面遷移を抑止
  let url = $(e.target).attr('href');  // href からダウンロード URL 取得

  const xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);   // ダウンロード先 URL 設定
  xhr.responseType = 'blob';   // バイナリデータ取得であることを指示

  // ダウンロード完了後の処理を設定。この時点ではデータは取得してクライアントにありますが保存はしていません。
  xhr.onload = function (oEvent) {
    if (xhr.status !== 200) {
      console.log(`データの取得に失敗しました。(status=${xhr.status})`);
    } else {
      // 取得したデータ
      let blob = xhr.response;

      // レスポンスヘッダーからサーバーから送られてきたファイル名を取得する
      let fileName = '';
      let disposition = xhr.getResponseHeader('Content-Disposition');
      if (disposition && disposition.indexOf('attachment') !== -1) {
        let filenameRegex = /filename[^;=\n]=((['"]).*?\2|[^;\n]*)/;
        let matches = filenameRegex.exec(disposition);
        if (matches != null && matches[1]) {
          // 「filename*=UTF-8''%E3%83%87%E3%83%BC%E3%82%BF.txt;」からファイル名を取得
          fileName = decodeURI(matches[1].replace(/['"]/g, '').replace('utf-8', '').replace('UTF-8', ''));
        }
      }
      if (fileName === '') {
        // ファイル名を取得できなかったら念のため URL をファイル名とする
        let fileName = url.match('.+/(.+?)([\?#;].*)?$')[1];
      }

      // Blob オブジェクトを指す URL オブジェクトを作る
      let objectURL = window.URL.createObjectURL(blob);
      // リンク(<a>要素)を生成し、JavaScript からクリックする
      let link = document.createElement('a');
      document.body.appendChild(link);
      link.href = objectURL;
      link.download = fileName;   // download を指定するとブラウザで開くことなくダウンロードになる
      link.click();
      document.body.removeChild(link);

      console.log('ダウンロードを完了しました。');
    }
  };

  // リクエスト開始
  xhr.send();
});

a आम तौर पर, यदि आप तत्व को क्लिक करते हैं, तो डिफ़ॉल्ट डाउनलोड प्रक्रिया आगे बढ़ेगी, इसलिए e.preventDefault(); हम डिफ़ॉल्ट प्रक्रिया को अक्षम करने के लिए कॉल करते हैं।

href से डाउनलोड URL प्राप्त करें और XMLHttpRequest GET इसे प्राप्त करने के लिए सेट करें।

XMLHttpRequest.responseTypeblob बाइनरी डेटा को डाउनलोड करने का निर्देश देने के लिए।

XMLHttpRequest.onload चूंकि डेटा डाउनलोड पूरा होने के बाद की प्रक्रिया को घटना में वर्णित किया जा सकता है, डाउनलोड पूरा होने के बाद की प्रक्रिया यहां लिखी गई है। चूंकि डेटा केवल क्लाइंट को डाउनलोड किया गया है, इसलिए फ़ाइल वास्तव में स्थानीय रूप से संग्रहीत नहीं है। किसी फ़ाइल को स्थानीय रूप से सहेजने के लिए, आप एक टैग जोड़ सकते हैं जिसमें a छद्म डेटा होता है और ऐसा व्यवहार कर सकते हैं जैसे कि आपने किसी लिंक पर क्लिक किया हो और फ़ाइल को सहेजा हो। उस समय के डेटा को फ़ंक्शन द्वारा URL में परिवर्तित किया जा सकता window.URL.createObjectURL है, इसलिए href आप इसे सेट कर सकते हैं और इसे काम कर सकते हैं।

सहेजे जाने वाले फ़ाइल नाम को प्रतिक्रिया शीर्षलेख से पुनर्प्राप्त किया जा सकता है यदि यह सर्वर से Content-Disposition प्रतिक्रिया में शामिल है। चूंकि यह हासिल करने के लिए थोड़ा जटिल है, मुझे लगता है कि कोड का उपयोग किया जाना चाहिए जैसा कि यह है। यदि सर्वर पर फ़ाइल नाम निर्दिष्ट नहीं है, तो इसकी मदद नहीं की जा सकती है, इसलिए मुझे लगता है कि इसे डिफ़ॉल्ट फ़ाइल नाम या URL पथ के अंत में फ़ाइल नाम पर सेट किया जाएगा।

चूंकि इस बार मैं फ़ाइल को सहेजने के बाद केवल कंसोल में प्रदर्शित करता हूं, मुझे लगता है कि वांछित ऑपरेशन को मनमाने ढंग से कोड के साथ इस भाग को फिर से लिखकर निष्पादित किया जा सकता है।

एक बार डेटा डाउनलोड प्रक्रिया का वर्णन करने के बाद, आखिरी चीज जो हम करना चाहते हैं वह वास्तव में अनुरोध शुरू करने के लिए एक फ़ंक्शन को कॉल करना है XMLHttpRequest.send

रन लिंक डाउनलोड करें

श्री/सुश्री कोड फ़ाइल को सीधे डाउनलोड करने के पैटर्न और जावास्क्रिप्ट के साथ इसे डाउनलोड करने के पैटर्न के लिंक प्रदान करता है। a आप URL को सीधे टैग में href लिख सकते हैं, लेकिन यदि आप ASP.NET Core में निम्न लिखते हैं, तो URL स्वचालित रूप से href .

रेजर पेज : Pages/index.cshtml

<ul>
  <li><a asp-page-handler="Download">ダウンロード (Javascript なし)</a></li>
  <li><a asp-page-handler="Download" id="download">ダウンロード (Javascript あり)</a></li>
</ul>

MVC : दृश्य/घर/index.cshtml

<ul>
  <li><a asp-controller="Home" asp-action="Download">ダウンロード (Javascript なし)</a></li>
  <li><a asp-controller="Home" asp-action="Download" id="download">ダウンロード (Javascript あり)</a></li>
</ul>