مع تطور تكنولوجيا الواجهة الأمامية، تتطلب المزيد والمزيد من سيناريوهات الأعمال واجهة أمامية للتعامل مع تنزيلات الملفات. من بين الطرق العديدة، يعد التنزيل من خلال سمة التنزيل للعلامة <a>
طريقة شائعة وبسيطة نسبيًا.
تطبق العلامة <a>
التقليدية رابطًا سريعًا عبر href إذا كنت تريد فقط تنزيل الملف بدلاً من القفز للمعاينة، فإن أفضل طريقة هي إضافة سمة download
في العلامة <a>
، ويمكن تحقيق عملية التنزيل بسهولة. .
download
هو سمة جديدة للعلامة <a>
في HTML5، ستفرض هذه السمة تشغيل عملية التنزيل، وتطلب من المتصفح تنزيل عنوان URL بدلاً من الانتقال إليه، وتطالب المستخدم بحفظه كملف محلي، على سبيل المثال:
<a href=result.png تنزيل>تنزيل</a>
إذا كانت سمة download
مفقودة، فسيتغير النقر فوق التنزيل مباشرةً إلى صورة المعاينة. عند إضافة سمة download
، سيتم تشغيل تنزيل الصورة.
التوافق الحالي لسمة download
كما هو موضح في caniuse:
يمكن أن نرى أن معظم المتصفحات السائدة تدعم بشكل أساسي سمة download
، وأداء IE مثير للإعجاب كما كان دائمًا، ولا تزال العديد من أنظمة Windows تستخدم IE، وهو أيضًا شيء يحتاج العديد من الشركات إلى مراعاته. تحد مشكلة التوافق هذه من التطبيق الأوسع download
.
في مواجهة بعض سيناريوهات الأعمال لتنزيل المحتوى الديناميكي، أي أن عناوين الموارد مثل الصور غير ثابتة (مثل الصور التي تم إنشاؤها بواسطة بعض أدوات الرسم عبر الإنترنت)، فإن استخدام HTML فقط لا يمكنه تلبية الاحتياجات. من أجل تلبية تنزيلات URL المختلفة، يمكن تنفيذ طريقة لتشغيل تنزيلات URL ديناميكيًا من خلال JS.
وظيفة تنزيل (href, filename='') { const a = document.createElement('a') a.download = filename a.href = href document.body.appendChild(a) a.click() a.remove() }
تجدر الإشارة إلى أن عمليات appendChild
remove
التي يتم إجراؤها على <a>
التي تم إنشاؤها في الكود تهدف بشكل أساسي إلى التوافق مع متصفح FireFox. عند استدعاء هذه الطريقة ضمن متصفح FireFox، إذا لم تقم بإضافة العلامة <a>
التي تم إنشاؤها إلى في النص، انقر على الرابط ولن يفعل شيئًا وسيؤدي إلى التنزيل، وهذا ليس هو الحال في Chrome.
يمكن للطريقة المذكورة أعلاه تحقيق تنزيل الموارد من نفس المصدر. ولكن في العديد من السيناريوهات، تحتاج الموارد عبر المجالات أيضًا إلى المعالجة. لسوء الحظ، تنطبق سمة download
حاليًا فقط على عناوين URL ذات الأصل نفسه . أي أنه إذا كان عنوان المورد المراد تنزيله عبر النطاق، فستكون سمة download
غير صالحة وسيتحول النقر فوق الارتباط إلى معاينة تنقل.
الاختبار: انقر للتنزيل، والنتيجة مجرد معاينة ولا يمكن تنزيل الصورة.
ملاحظة: كان Chrome 65 يدعم سابقًا سمة download
لتشغيل تنزيلات الملفات عبر النطاقات، وبعد ذلك، اتبع بصرامة سياسة المصدر نفسه ولم يعد بإمكانه تشغيل تنزيل الموارد عبر النطاقات من خلال سمة download
. لم يدعم FireFox سمة download
للموارد عبر النطاقات.
لا يمكن لسمة download
تشغيل التنزيلات فحسب، بل يمكنها أيضًا تحديد اسم ملف التنزيل:
<a href=test.png download=joker.png>تنزيل</a>
إذا كانت لاحقة الملف الذي تم تنزيله متوافقة مع الملف المصدر، فيمكنك تعيين اسم الملف الافتراضي:
<a href=test.png download=joker>تنزيل</a>
واجه المؤلف ذات مرة مشكلة، حيث أدى إلى تنزيل الموارد عبر النطاقات من خلال العلامة <a>
. الكود هو في الأساس نفس طريقة التنزيل المذكورة أعلاه، باستثناء أن مكان تعيين سمة download
مختلف قليلاً:
a.setAttribute(تنزيل، صحيح)
ونتيجة لذلك، حدث الموقف التالي في الإصدار القديم من متصفح Chrome.
يصبح اسم ملف التنزيل true
. من الواضح أن المتصفح يقرأ قيمة سمة download
كاسم الملف.
بعد التحليل، ترجع المشاكل المذكورة أعلاه بشكل رئيسي إلى:
1. أولاً، لا ينبغي تعيين download
على true
، حيث تختلف قيمة سمة download
عن disabled
، فهي مرتبطة مباشرة باسم الملف. وبالنسبة لطريقة التنزيل المستجيبة للواجهة الأمامية والخلفية هذه، فإن سمة download
ليست ضرورية.
2. لم تدعم الإصدارات القديمة من Chrome سمة download
للموارد عبر النطاقات فحسب، بل أعادت أيضًا تعيين أسماء الملفات للموارد عبر النطاقات من خلال download
، لذلك حدث الموقف أعلاه.
يتم تنفيذ سيناريو العمل الذي تتعاون فيه الواجهة الأمامية والخلفية لإكمال تنزيل الملف بشكل عام من خلال إعداد الواجهة الخلفية لمعلومات Content-Disposition
في رأس الاستجابة.
في سيناريو HTTP، تكون المعلمة الأولى لترتيب المحتوى إما مضمنة (القيمة الافتراضية، التي تشير إلى أن نص الرسالة في الرد سيتم عرضه كجزء من الصفحة أو الصفحة بأكملها)، أو مرفق (بمعنى أن نص الرسالة يجب تنزيله على الموقع المحلي؛ ستقدم معظم المتصفحات مربع حوار "حفظ باسم"، مع ملء قيمة اسم الملف مسبقًا باسم الملف الذي تم تنزيله).
إذا تم تعيين Content-Disposition
في رأس الاستجابة وأضافت الواجهة الأمامية أيضًا سمة download
إلى علامة <a>
للرابط المقابل، فإن قواعد التسمية في هذا الوقت هي:
إذا تم تعيين اسم ملف مختلف عن هذه السمة لسمة ترتيب المحتوى في رأس HTTP، فإن سمة رأس HTTP لها الأولوية على هذه السمة.
بعد الاختبار، وجد أنه عندما لا يكون Content-Disposition
في رأس HTTP فارغًا:
في متصفح Chrome، بغض النظر عما إذا تم تعيين المعلمة الأولى لـ Content-Disposition
في رأس HTTP على مرفق أو مضمّن ، فلا يمكن download
إعادة تعيين اسم الملف طالما تم تعيين اسم الملف. على العكس من ذلك، عندما يكون اسم الملف فارغًا، سيتم تعيين قيمة سمة download
على اسم الملف. في متصفح FireFox، سيقرأ المتصفح فقط قيمة اسم الملف الخاص بـ Content-Disposition
، وإذا كان اسم الملف فارغًا، فسيتم أخذ اسم الملف المصدر. في هذا الوقت، لا يمكن download
إعادة تعيين اسم الملف على أية حال.
للتلخيص: إذا لم يتم تعيين معلومات Content-Disposition
في رأس الاستجابة (على سبيل المثال، عنوان URL من نفس المصدر الذي يحدد موقع المورد بشكل مباشر بشكل عام)، فيمكن لسمة download
إعادة تعيين اسم الملف. إذا قامت الواجهة الخلفية بتعيين اسم ملف في حقل Content-Disposition
، فستسود قيمة اسم الملف.
ماذا علي أن أفعل إذا كنت لا أزال أرغب في إعادة تعيين اسم الملف بعد تعيين اسم الملف على الواجهة الخلفية؟
النقطة: URL هناك أيضًا مقدمة لسمة download
:
على الرغم من أن عنوان URL الخاص بـ HTTP يجب أن يكون من نفس الأصل، إلا أنه يمكنك استخدام blob: URL وdata: URL لتسهيل قيام المستخدمين بتنزيل المحتوى الذي تم إنشاؤه باستخدام JavaScript (مثل الصور التي تم إنشاؤها باستخدام تطبيق ويب للرسم عبر الإنترنت).
Blob
(كائن ثنائي كبير) هو كائن ثنائي كبير، ونحن لسنا على دراية بهذا. تستخدم بعض قواعد البيانات Blob لتمثيل نوع الحقل الذي يخزن الملفات الثنائية. تعتمد واجهة الملف أيضًا على Blob، حيث ترث وظائف Blob وتوسعها لدعم الملفات الموجودة على نظام المستخدم. يتم إنشاء كائنات Blob باستخدام مُنشئ Blob:
النقطة (blobParts [، الخيارات])
var debug = {hello:world};var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});
إذا كنت بحاجة إلى تنزيل بعض النصوص البسيطة أو ملفات سلسلة JS، فيمكنك تحويل المعلومات النصية إلى دفق ثنائي ثنائي، وإنشاء عنوان URL لـ Blob، واستخدام سمة download
لإكمال التنزيل.
const downloadText = (text, filename = '') { const a = document.createElement('a') a.download = filename const blob = new Blob([text], {type: 'text/plain'}) // يشير النص إلى النص أو محتوى السلسلة الذي يجب تنزيله a.href = window.URL.createObjectURL(blob) // سلسلة عنوان URL مشابهة لـ blob:http://localhost:8080/d3958f5c-0777-0845-9dcf-2cb28783acaf سيتم إنشاء document.body.appendChild(a) a.click() a.remove()}
ما الفرق بين عنوان URL Blob هذا وعنوان URL الشائع لـ HTTP؟
Blob URL/Object URL هو بروتوكول زائف يسمح باستخدام كائنات Blob وFile كمصادر URL مثل الصور وروابط تنزيل البيانات الثنائية.
يقوم المتصفح بإنشاء مرجع خاص إلى كائن Blob أو File داخليًا من خلال URL.createObjectURL()
لا يمكن استخدام عنوان URL الخاص بـ Blob الذي تم إنشاؤه إلا في مثيل واحد للمتصفح وفي نفس الجلسة، وسيتم استخدام كائن URL هذا عندما يكون يتم إصدار الصفحة بواسطة المتصفح.
لذلك، لا يمكن أن يشير عنوان URL الخاص بالكائن الثنائي الكبير إلى مورد خادم ولا يمكنك فتحه في صفحات أخرى. في الوقت نفسه، نظرًا للاختلافات في تنسيقات التشفير، تشغل عناوين URL Blob موارد مساحة أقل وتعمل بشكل أفضل من عناوين URL للبيانات.
توفر الكائنات الثنائية الكبيرة ميزة مفيدة جدًا لتطوير الويب: إنشاء عناوين URL للكائنات الثنائية الكبيرة. قم بتغليف البيانات الثنائية في كائن Blob، ثم استخدم URL.createObjectURL()
لإنشاء عنوان URL لـ Blob نظرًا لأن عنوان URL الخاص بـ Blob نفسه هو عنوان URL من نفس الأصل، فيمكنك استخدام عنوان URL هذا مع download
لحل مشكلة التنزيل والتسمية. الموارد عبر المجال.
يمكن لـ Blob وFetch حل مشكلة عبر النطاقات وتسمية الملفات: استخدم fetch
للحصول على موارد عبر النطاقات، وإرجاع كائن blob وإنشاء عنوان URL لـ Blob، وتشغيل التنزيل باستخدام سمة download
للعلامة <a>
الكود هو كما يلي:
وظيفة تنزيل (href, filename = '') { const a = document.createElement('a') a.download = filename a.href = href document.body.appendChild(a) a.click() a.remove() }وظيفة downloadFile(url, filename='') { fetch(url, { headers: new Headers({ Origin: location.origin, })، الوضع: 'cors'، }) .then(res => res.blob()) .then(blob => { const blobUrl = window.URL.createObjectURL(blob) download(blobUrl, filename) window.URL.revocObjectURL(blobUrl) })}
عند هذه النقطة، انقر فوق "تنزيل" مرة أخرى، ويمكن تنزيل الصور عبر النطاقات إلى المنطقة المحلية بشكل طبيعي.
تجدر الإشارة إلى أن الخادم الذي توجد به الموارد عبر النطاقات يحتاج إلى تكوينه باستخدام معلومات Access-Control-Allow-Origin
، وإلا فسوف تحصل على خطأ كبير عبر النطاقات. مثال لتكوين الرأس:
// السماح لأي اسم مجال بالوصول إلى الرأس('Access-Control-Allow-Origin: *'); // حدد اسم المجال للوصول إلى الرأس('Access-Control-Allow-Origin: https://h5.ele.me ');
لا تزال هناك بعض العيوب في هذه الطريقة، على سبيل المثال، سيحد المتصفح من حجم بيانات Blob بما لا يزيد عن 500 ميجا، كما أنها لن تكون كافية من حيث الأداء.
تلخيص يوجد حاليًا العديد من طرق التنزيل على الواجهة الأمامية، ويعد تنزيل سمة download
أحد أبسط الطرق، ومع ذلك، يمكن أن يكشف الفحص الدقيق لبعض هذه الميزات أيضًا عن الكثير من المعلومات المفيدة. يرتبط download
ارتباطًا وثيقًا بميزات المتصفح. في الوقت الحالي، يعد توافق هذه السمة أيضًا مشكلة كبيرة، ومع ذلك، حتى مسؤولي Microsoft يناشدون المستخدمين عدم استخدام IE بعد الآن، وأعتقد أن مشكلة توافق download
ستستمر في التحسن المستقبل، وآفاق التطبيق سوف تصبح أكثر وأكثر شعبية.
ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.