يعمل طلب GET من المستعرض لتنزيل الملف إلى ملف محلي ولكن XMLHttpRequest Javascript script لا يقوم بتنزيل الملف

0

أواجه مشكلة مع XMLHttpRequest ، أعتقد أنه عندما أنتقل إلى localhost / dashboard / downloadfile؟ file-name = hw3.txt يتم تنزيل الملف محليًا ولكن إذا كنت تستخدم الوظيفة checkDownload () لبدء XMLHttpRequest ، فلن يتم تنزيل الملف .

إليك رمز العميل:

function checkDownload() {
  const filename = "hw3.txt";
  const xhr = new XMLHttpRequest();
  xhr.responseType = "blob";
  xhr.open('GET', `/dashboard/downloadfile?file-name=${ filename }`);
  xhr.onreadystatechange = () => {
    if(xhr.readyState === 4) {
      if(xhr.status === 200) {

      }
    }
  }
  xhr.send();
}

ثم هنا هو رمز الخادم الخاص بي:

app.get('/dashboard/downloadfile', requiresLogin, (req, res) => {
  const userid = req.user.id;
  const filename = req.query['file-name'];

  db.getFileKey([userid, filename], (keyres) => {
    const params = {
      Bucket: S3_BUCKET,
      Key: keyres.rows[0].filekey,
    };


    res.setHeader('Content-disposition', `attachment; filename=${ filename }`);
    res.setHeader('Content-type', `${ mime.getType(keyres.rows[0].filetype) }`);
    s3.getObject(params, (awserr, awsres) => {
      if(awserr) console.log(awserr);
      else console.log(awsres);
    }).createReadStream().pipe(res);
  });
});

3 الاجابة

0

حصلت عليها تعمل. بدلاً من محاولة إنشاء دفق قراءة من s3.getObject() لقد قمت بإنشاء عنوان URL موقع لكائن s3 على الخادم وأعدته إلى العميل ، ثم استخدمت عنصر html 'a' مع element.href = signedRequest واستخدم جافا سكريبت للنقر على هذا العنصر. المشكلة الجديدة التي أواجهها هي أنه لا يمكنني اكتشاف طريقة لتعيين البيانات الوصفية للكائن s3 عند تحميله في البداية ، كنت بحاجة إلى تغيير البيانات الوصفية يدويًا على كائن s3 فردي من خلال وحدة تحكم aws بحيث يحتوي على الرأس Content-Disposition: attachment; filename=${ filename } .

رمز العميل الذي تم تغييره:

function initDownload(filename) {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', `/sign-s3-get-request?file-name=${ filename }`);
  xhr.onreadystatechange = () => {
    if(xhr.readyState === 4) {
      if(xhr.status === 200) {
        const response = JSON.parse(xhr.responseText);
        startDownload(response.signedRequest, response.url);
      }
    }
  }
  xhr.send();
}

function startDownload(signedRequest, url) {
  var link = document.createElement('a');
  link.href = signedRequest;
  link.setAttribute('download', 'download');
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

رمز الخادم الذي تم تغييره:

app.get('/sign-s3-get-request', requiresLogin, (req, res) => {
  const userid = req.user.id;
  const filename = req.query['file-name'];

  db.getFileKey([userid, filename], (keyres) => {
    const s3Params = {
      Bucket: S3_BUCKET,
      Key: keyres.rows[0].filekey,
      Expires: 60,
    };

    s3.getSignedUrl('getObject', s3Params, (err, data) => {
      if (err) {
        // eslint-disable-next-line
        console.log(err);
        res.end();
      }
      const returnData = {
        signedRequest: data,
        url: `https://${S3_BUCKET}.s3.amazonaws.com/${ keyres.rows[0].filekey }`,
      };
      res.write(JSON.stringify(returnData));
      res.end();
    });
  });
});
:مؤلف
0

لتنزيل عنوان URL ، يمكنك استخدام السمة download من a بطاقة شعار:

<a download="something.txt" href="https://google.com">Download Google</a>

إذا كنت تستخدم xhr.responseType = "blob" عليك القيام بشيء مثل:

function checkDownload() {
  const filename = "hw3.txt";
  const xhr = new XMLHttpRequest();
  xhr.responseType = "blob";
  xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
  xhr.onreadystatechange = () => {
    if(xhr.readyState === 4) {
      if(xhr.status === 200) {      
      var reader = new FileReader();
      reader.readAsArrayBuffer(xhr.response);      
      reader.addEventListener("loadend", function() {  
       var a = new Int8Array(reader.result);
      console.log(JSON.stringify(a, null, '  '));
});
      }
    }
  }
  xhr.send();
}

checkDownload()

لكن هذا الرمز لا ينزل الملف.

:مؤلف
0

أنت تحصل على نقطة من الخادم ، لذلك من أجل التنزيل ، عليك أن تفعل شيئًا متى xhr.status === 200 .

شيء من هذا القبيل:

...
if(xhr.status === 200) {
   var fileUrl = URL.createObjectURL(xhr.responseText)
   window.location.replace(fileUrl)
}
...  
:مؤلف

أسئلة ذات صلة

فوق
قائمة طعام