【问题标题】:XHR upload onprogress Event not Working on HTTPS ConnectionXHR 上传 onprogress 事件在 HTTPS 连接上不起作用
【发布时间】:2019-07-21 16:10:15
【问题描述】:

我有一个通过 Angular 7 和 Node.Js 将文件上传到 AWS S3 的设置。上传工作正常。但是xhr.upload.onprogress 事件存在问题。

此事件仅在通过http 托管服务器时触发。使用https 连接时,不会触发一次事件。

我在 heroku 和我的 EC2 实例上对其进行了测试,得出的结论是只有 http 有效。因此,我通过 https 托管在 AWS 上的生产应用程序也不起作用。

这是代码(如果需要更多详细信息,请写评论):

Angular 服务(前端)

const xhr = new XMLHttpRequest();
let progress = 0;
xhr.upload.onprogress = (event: ProgressEvent) => {
    console.log('xhr on upload', event);
    if (event.lengthComputable) {
        progress = 100 * (event.loaded / event.total);
        console.log('file upload progress', { progress, file });
    }
};
xhr.responseType = 'json';
xhr.open('POST', `${API_URL}/${this.API_PATH}/upload`, true);
xhr.setRequestHeader('authorization', this.authService.getAuthToken());
xhr.send(payload);
xhr.onload = () => {
    observer.next(xhr.response);
    observer.complete();
    alive = false;
};

Node.Js

module.exports = async (req, res) => {
    try {
        const busboy = new Busboy({ headers: req.headers })
        busboy.on('finish', async () => {
            const fileData = req.files.file
            const fileId = req.body.fileId
            await uploadToAws(fileData)
            // ...
        })
        req.pipe(busboy)
    } catch (err) { /* ... */ }
}
const uploadToAws = async (fileData, file) => {
    return new Promise((resolve, reject) => {
        const params = {
            Body: fileData.data,
            Bucket: awsConfig.buckets.drakery,
            ContentType: fileData.mimetype,
            Key: `mykey`,
            StorageClass: 'ONEZONE_IA',
        }
        awsConfig.s3
        .upload(params, (err, data) => err ? reject(err) : resolve(data.Location))
        .on('httpUploadProgress', function (evt) {
            console.log('httpUploadProgress', evt);
        })
})

我真的很困惑为什么会这样。我在网上找不到任何关于这个问题的资源。

我真的很感谢每一个帮助!

谢谢

【问题讨论】:

  • xhr.onload 是做什么的?尝试删除它,看看它是否有效。您还可以在请求中添加 content-type 标头。
  • xhr.onload 在请求完成时被调用...我添加了一个 content-type 并删除了 xhr.onload 但它仍然不适用于 https 连接
  • 文件是否到达您的 Node.js 服务器,或者通过 HTTPs 提供时它甚至没有到达那么远?您确定在通过 HTTPS 提供服务时,您不会通过发布到 HTTP:// 而不是 HTTPS:// 之类的操作意外地发出跨源请求吗?您的主机在工作时的价值是多少,不工作时的价值是多少?(我说的是${API_URL}/${this.API_PATH}/upload
  • 文件可以很好地到达服务器(也可以通过 https) --- 我没有发出跨源请求 ---- API_URL = `${window.location.protocol}//${ window.location.hostname}:3000/api
  • @friek108 真的很奇怪。也许你可以看看这个问题:stackoverflow.com/questions/55782997

标签: javascript node.js angular https xmlhttprequest


【解决方案1】:

这是我用于 Web 项目的基本 js 代码:

        ...
        var xhr = new XMLHttpRequest();

        xhr.upload.addEventListener("progress", uploadProgress, false);

        xhr.addEventListener("load", uploadComplete, false);

        xhr.addEventListener("error", uploadFailed, false);

        xhr.addEventListener("abort", uploadCanceled, false);

        xhr.open("POST", "/controller");
        // fd : formData
        xhr.send(fd);

    }

    function uploadProgress(evt) {

        if (evt.lengthComputable) {

            var percentComplete = Math.round(evt.loaded * 100 / evt.total);
            ...
        }

        else {

            ...
        }

    }

如您所见,我在“进度”上添加了一个事件侦听器,我没有像您使用 (=) 那样覆盖其他回调函数(也许 https 使用另一个回调并像您一样覆盖 onprogress回调不能正常工作):

xhr.upload.onprogress = (event: ProgressEvent) => {
    console.log('xhr on upload', event);
    if (event.lengthComputable) {
        progress = 100 * (event.loaded / event.total);
        console.log('file upload progress', { progress, file });
    }
};

试试这个,希望对你有帮助,祝你有美好的一天

【讨论】:

  • 非常感谢您的努力,但不幸的是,该事件也没有触发:(
猜你喜欢
  • 2019-06-20
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 2013-10-08
相关资源
最近更新 更多