"Javascript", kad būtų galima atlikti apdorojimą atsisiuntus failą
Veikimo tikrinimo aplinka
- Vizualinė studija
-
- "Visual Studio 2022"
- ASP.NET branduolys
-
- 8.0 ("Razpr" puslapiai, MVC)
- Žiniatinklio naršyklės
-
- kraštas 119
Darbo aplinka
- "Visual Studio" (jei taip pat įtraukiate serverio programas)
-
- "Visual Studio 2022"
- ASP.NET Core (jei jame taip pat yra serverio programų)
-
- 8.0 ("Razpr" puslapiai, MVC)
- Žiniatinklio naršyklės
-
- Kraštas
- "Google Chrome"
- Kitos naršyklės (ne visos patikrintos)
(* Pagrindinis šio patarimo elementas yra kliento pusės procesas, todėl serverio pusė gali būti bet kas)
Iš pradžių
Pagrindinis šių patarimų dėmesys skiriamas kliento programai ("Javascript"), o serverio programa yra tik failams atsisiųsti. Todėl nesvarbu, kokia yra serverio programa, jei ji gali priversti jus atsisiųsti failą.
Ar vartotojai atsisiunčia failus, kai jie pasiekiami serveryje
Mr./Ms. leidžia atsisiųsti failus, kai gaunate užklausą. Tuo metu mes sąmoningai laukiame tam tikro laiko serveryje, kad būtų lengva suprasti atsisiuntimo pradžią ir pabaigą.
Štai kas vyksta "Razor Pages" ir "MVC" serverio pusėje: Jį galite įdiegti kituose projektuose, pvz., žiniatinklio API.
Skustuvo puslapiai : Puslapiai/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");
}
}
}
MVC : Coletollers/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");
}
}
}
Kliento apdorojimas
Paprastai failą atsisiunčiate žiniatinklio naršyklėje pasiekdami nurodytą URL. Jei norite ką nors padaryti, kai atsisiuntimas bus baigtas, galite paleisti atsisiuntimą naudodami "Javascript".
Yra daug būdų tai padaryti, tačiau šiuo atveju mes naudosime , kuris taip pat XMLHttpRequest
yra asinchroninio apdorojimo kilmė.
Taip pat galite naudoti jQuery ajax funkcijas arba Fetch API.
a
href
Atsisiuntimo URL įrašomas į žymą ir id
procesas vykdomas, kai spustelėjamas tas, kuris nustatytas į download
būseną.
$('#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
Paprastai, jei paliksite elementą spustelėtą, numatytasis atsisiuntimo procesas bus perkeltas, todėl e.preventDefault();
raginame išjungti numatytąjį procesą.
href
Gaukite atsisiuntimo URL iš ir XMLHttpRequest
GET
nustatykite, kad jis gautų iš .
XMLHttpRequest.responseType
blob
nurodyti atsisiųsti dvejetainius duomenis.
XMLHttpRequest.onload
Kadangi procesas po duomenų atsisiuntimo gali būti aprašytas įvykio metu, procesas po atsisiuntimo yra parašytas čia.
Kadangi duomenys buvo atsisiųsti tik į klientą, failas iš tikrųjų nėra saugomas vietoje.
Norėdami išsaugoti failą vietoje, galite pridėti žymą, kurioje a
yra pseudoduomenų, ir priversti jį elgtis taip, lyg būtumėte spustelėję nuorodą ir išsaugoję failą.
Tuo metu duomenis funkcija gali window.URL.createObjectURL
konvertuoti į URL, kad href
galėtumėte juos nustatyti ir priversti juos veikti.
Įrašytiną failo vardą galima nuskaityti iš atsakymo antraštės, jei jis įtrauktas į serverio atsakymą Content-Disposition
.
Kadangi tai yra šiek tiek sudėtinga įsigyti, manau, kad kodas turėtų būti naudojamas toks, koks yra.
Jei failo vardas nenurodytas serveryje, jam negalima padėti, todėl manau, kad URL kelio pabaigoje jis bus nustatytas į numatytąjį failo pavadinimą arba failo pavadinimą.
Kadangi šį kartą aš jį rodau konsolėje tik išsaugojęs failą, manau, kad norimą operaciją galima atlikti perrašant šią dalį savavališku kodu.
Aprašius duomenų atsisiuntimo procesą, paskutinis dalykas, kurį norime padaryti, yra XMLHttpRequest.send
iškviesti funkciją, kad iš tikrųjų pradėtume užklausą.
Atsisiųskite paleidimo nuorodą
Mr./Ms. Code pateikia nuorodas į tiesioginio failo atsisiuntimo modelį ir jo atsisiuntimo naudojant "Javascript" modelį.
a
URL galite įrašyti tiesiai į href
žymą, bet jei "ASP.NET Core" parašysite toliau nurodytus dalykus, URL bus automatiškai href
išplėstas į .
Skustuvo puslapiai : 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 : Peržiūros/Pagrindinis/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>