تعذر تنزيل js attachment

أحصل على نفس الخطأ تمامًا كما في هذا السؤال، أي أنه يمكنني رفع ملفات JS بعد السماح بذلك في الإعدادات، ولكن عند محاولة تنزيلها، يتغير الرابط في المتصفح إلى رابط ملف JS، ويتم عرض الرسالة “تم رفض التغيير الذي أردته”.

البيئة:

Discourse تعمل عبر Docker خلف Nginx (يستخدم Nginx SSL)

سجلات حاوية Discourse:

    Started GET "p5ePkm5OoKveknnMjyArlS4PPwS.js" for 192.168.32.1 at 2021-02-22 05:48:52 +0000
    Processing by UploadsController#show_short as JS
      Parameters: {"base62"=>"p5ePkm5OoKveknnMjyArlS4PPwS", "extension"=>"js"}
    Sent file afcdf626f9db8d54a1fb5e8ebcab0ea214d9226a.js (2.2ms)
    Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.
    Completed 422 Unprocessable Entity in 59ms (ActiveRecord: 0.0ms | Allocations: 17414)
    ActionController::InvalidCrossOriginRequest (Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.)
    /opt/bitnami/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.3.1/lib/action_controller/metal/request_forgery_protection.rb:266:in `verify_same_origin_request'

سجلات Nginx:

    10.164.0.103 - - [22/Feb/2021:05:51:11 +0000] "GET /uploads/short-url/p5ePkm5OoKveknnMjyArlS4PPwS.js HTTP/2.0" 422 781 "getting-started-with-sftp-module/292" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"

أي مساعدة أو توجيهات موضع تقدير!

إعجابَين (2)

هل تسمح بملفات *.js التي يرفقها المستخدمون بالمنشورات؟ هل لديك حاجة مشروعة لملفات جافا سكريبت التي يرفقها المستخدمون؟ نود التأكد تمامًا قبل المضي قدمًا.

إعجاب واحد (1)

شكرًا لك على الرد السريع!
نعم، هذه مناقشة حول الأسئلة والأجوبة البرمجية، لذا فإن إرفاق ملفات كود *.js هو حالة استخدام مشروعة.

إعجابَين (2)

مرحبًا بالجميع! أعاني من نفس المشكلة. لقد سمحنا برفع الملفات ذات الامتداد .js، لكن لا يمكن لأي شخص تنزيلها. لم نعثر حتى الآن على أي إعداد لحل هذه المشكلة. هل يمكن لأي شخص المساعدة؟

إعجاب واحد (1)

هل يمكنك وصف حالة الاستخدام؟ لماذا هذا ضروري؟

مرحبًا جيف،

رغم أننا الآن ننسخ الكود ونلصقه في قسم النص للمناقشة.
حالة الاستخدام: لدينا ملف .js يحتوي على كود Kickstarter أو حل لمشكلة متكررة، ونريد مشاركته كمرفق حتى يتمكن المستخدمون من تنزيله والبدء في استخدامه في مشاريعهم.

ومع ذلك، عند تغيير امتداد الملف من .js إلى .txt، يظهر مرة أخرى رسالة “تم رفض التغيير المطلوب”. (قد يكون ذلك بسبب بعض تحسينات التخزين في الخلفية، حيث أنه إذا كان الملف يحتوي على نفس المحتوى مثل ملف سابق، فإن المرفق الجديد يشير إلى الملف المرفق سابقًا).
لذلك، قمت بتعديل محتوى ملف .js (الذي كان امتداده .txt) قليلاً وقمت برفعه مرة أخرى، وتمكنت من تنزيل الملف كمرفق.

@codinghorror هل هناك خطر أمني في السماح بتنزيل ملفات .js؟

إعجاب واحد (1)

نعم؛ نحتاج إلى إجراء بعض الأبحاث حول المتصفح للتأكد من أن الملف يُحمّل دائمًا إلى القرص ولا يُنفَّذ أبدًا.

إعجاب واحد (1)

لدينا منتدى للمطورين على fluiggers.com.br، تفضل بالنظر… وكثيرًا ما نشارك ملفات .js.

إعجاب واحد (1)

بالتأكيد، هناك العديد من مشاكل الأمان المتعلقة بالسماح بملفات JavaScript، لذا فإن الأمر يتطلب منا توخي حذر شديد.

سيؤدي رأس Content-Disposition إلى منع تنفيذ ملفات JS المُحمَّلة، ونحن نعيّنه بشكل صحيح:

attachment; filename="test.js"; filename*=UTF-8''test.js

يعمل هذا في حالات الرفع على S3، وينبغي أن يعمل أيضًا مع الرفع المحلي، لكن يبدو أن هناك إجراءً أمنيًا جديدًا نسبيًا من Rails:

ActionController::InvalidCrossOriginRequest (تحذير أمني: طلبت علامة المضمنة من موقع آخر جافا سكريبت محميًا. إذا كنت تعرف ما تفعله، فقم بتعطيل حماية التزوير في هذا الإجراء للسماح بتضمين جافا سكريبت عبر النطاقات.)

يجب أن يكون قابلاً للإصلاح…

3 إعجابات

لقد واجهت نفس المشكلة، لدينا منتدى للأسئلة والأجوبة البرمجية ونحتاج إلى أن نكون قادرين على مشاركة ملفات جافاسكريبت كبيرة للتنزيل

لدي نفس المشكلة في مجتمعي. يرغب الأشخاص في مشاركة ملفات JS ولكن عند محاولة تنزيلها، يواجهون هذا الخطأ:

مقتطف من سجل الإنتاج في Rails:

بدأ GET "/uploads/short-url/qDlrltMxEIJ2aYYdt8lZ200E3wA.js" لـ 94.31.111.247 في 2025-07-09 05:53:30 +0000
معالجة بواسطة UploadsController#show_short بصيغة JS
  المعلمات: {"base62"=>"qDlrltMxEIJ2aYYdt8lZ200E3wA", "extension"=>"js"}
تم إرسال الملف /var/www/discourse/public/uploads/default/original/1X/baab1fc131be960b601467333f5a690b257daeb0.js (0.3ms)
تحذير أمني: علامة <script> مضمنة على موقع آخر طلبت جافاسكريبت محمي. إذا كنت تعرف ما تفعله، فانتقل إلى تعطيل حماية التزوير في هذا الإجراء للسماح بتضمين جافاسكريبت عبر المصادر.
اكتمل 422 كيان غير قابل للمعالجة في 17 مللي ثانية (ActiveRecord: 0.0 مللي ثانية (0 استعلامات، 0 مخبأة) | GC: 0.0 مللي ثانية)

ملفات js موجودة في قائمة امتدادات التحميل المسموح بها:

نفس المشكلة هنا. لدينا ملفات JS تعمل داخل برنامجنا الخاص، ولا شيء منها قد يفعل أي شيء في المتصفح.

تمكنا من حل مشكلة تحميل Discourse بنقل جميع الملفات المرفوعة إلى سلة تخزين S3 وتعيين s3_use_cdn_url_for_all_uploads إلى true. هذا يتجاوز بشكل أساسي وحدة تحكم الروابط القصيرة التي تبدو أنها العائق الرئيسي أمام ملفات JS.

التفاصيل (من مساعدي الذكي الذي رافقني في هذه العملية):

  1. إعداد تخزين متوافق مع S3 (مثل Cloudflare R2)

لا يمكن لـ Discourse تقديم ملفات .js بأمان من القرص المحلي. انقلها إلى سلة تخزين.

  • السلة: أنشئ سلة خاصة (مثل my-discourse-bucket).

  • مفاتيح API: أنشئ مفتاح وصول ومفتاح سري.

2. تكوين نطاق CDN مخصص

في Cloudflare (أو مزود الخدمة لديك)، اربط نطاقًا مخصصًا بسلة التخزين (مثل cdn.example.com). يضمن ذلك تقديم الملفات كعناصر ثابتة عبر رابط مباشر، متجاوزًا “حارس الأمان” في Discourse.

3. تحديث إعدادات Discourse

في الإدارة → الإعدادات، قم بتكوين تفاصيل S3 الخاصة بك. من الأهمية بمكان، قم بتفعيل الخيارات التالية لضمان عدم محاولة Discourse “توقيع” الروابط باستخدام رؤوس مؤقتة قد تسبب تعطلًا:

  • s3_use_cdn_url_for_all_uploads: قم بتفعيل هذه المربع (هذه هي الخطوة الأهم).

  • s3_cdn_url: اضبطه على https://cdn.example.com.

  • s3_region: استخدم us-east-1 (للتوافق مع R2).

4. نقل الملفات المرفوعة الحالية (اختياري)

ملاحظة: هذا لم ينجح معنا لأسباب غير معروفة.

لإصلاح الروابط القديمة في المنشورات الموجودة، ادخل إلى الحاوية وقم بتشغيل:

Bash

# داخل /var/discourse
./launcher enter app
rake uploads:migrate_to_s3
rake posts:rebake

أتمنى أن يفيد هذا شخصًا ما.