XMLHttpRequest.upload.onprogress不适用于HTTPS [英] XMLHttpRequest.upload.onprogress not Working with HTTPS

查看:187
本文介绍了XMLHttpRequest.upload.onprogress不适用于HTTPS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题



我有一个页面,用户可以在其中通过 FormData XMLHttpRequest
上传文件正常。但是 upload.onprogress 仅在从HTTP连接上传 时有效。



HTTPS





HTTP





我已经在Heroku和Amazon EC2实例上对此进行了测试。但这始终是相同的:




  • 通过HTTP上传时显示进度

  • 从不显示进度事件通过HTTPS上传时触发



Javascript(角度7)



  const xhr =新的XMLHttpRequest(); 
让进度= 0;


/ **此事件不支持HTTPS * /
xhr.upload.onprogress =(事件:ProgressEvent)=> {
if(event.lengthComputable){
progress = 100 *(event.loaded / event.total);
}
};


xhr.responseType =‘json’;
xhr.open(’POST’,`$ {API_URL} / $ {this.API_PATH} / upload`,true);
xhr.setRequestHeader('authorization',this.authService.getAuthToken());
xhr.send(payload);
xhr.onload =()=> {
rator.next(xhr.response);
Observer.complete();
};



Node.Js



  const busboyBodyParser = require('busboy-body-parser'); 
app.use(busboyBodyParser())






  const busboy = new Busboy({headers:req.headers})
busboy.on('finish',async()=> {

const fileData = req.files.file
const fileId = req.body.fileId
const params = {
主体:fileData.data,
桶:awsConfig.bucket,
ContentType:fileData.mimetype,
键:fileId,
StorageClass:'ONEZONE_IA',
}
awsConfig.s3.upload(params,(err,data) => {/ * ... * /}

})
req.pipe(busboy)



我也尝试过的东西



我还尝试过使用 .addEventListener 用于监听进度的语法:

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

但这也不起作用。



源代码





用于测试的浏览器;



Firefox开发人员版67.0b13(64位/最新)

Google Chrome 74.0.3729.108(64位/ Up-迄今为止)


Issue

I have a page where users can upload files with the help of FormData and an XMLHttpRequest. Uploading the file works fine. But the upload.onprogress is only working when uploading from an HTTP connection.

HTTPS

HTTP

I've tested this on Heroku and on an Amazon EC2 instance. But it's always the same:

  • Progress is shown when uploading via HTTP
  • Progress event is never triggered when uploading via HTTPS

Javascript (Angular 7)

const xhr = new XMLHttpRequest();
let progress = 0;


/** THIS EVENT IS NOT WORKING WITH HTTPS */
xhr.upload.onprogress = (event: ProgressEvent) => {
    if (event.lengthComputable) {
        progress = 100 * (event.loaded / event.total);
    }
};


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();
};

Node.Js

const busboyBodyParser = require('busboy-body-parser');
app.use(busboyBodyParser())


const busboy = new Busboy({ headers: req.headers })
busboy.on('finish', async () => {

    const fileData = req.files.file
    const fileId = req.body.fileId
    const params = {
        Body: fileData.data,
        Bucket: awsConfig.bucket,
        ContentType: fileData.mimetype,
        Key: fileId,
        StorageClass: 'ONEZONE_IA',
    }
    awsConfig.s3.upload(params, (err, data) => { /* ... */ }

})
req.pipe(busboy)

What I've also tried

I also tried to use the .addEventListener syntax for listening for progress:

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

But this didn't work, either.

Source Code

Node.Js (server.js)

Node.Js (upload-file.js)

Angular Service (editor-file.service.ts)

Notes

Please note, that I have already asked a question about this topic. But I got no working answer and I really need this to work.

Old question: XHR upload onprogress Event not Working on HTTPS Connection

解决方案

As I've tried to reproduce this problem, I didn't face the same issue. Could you please check below simple Heroku app that I've created to test this specific problem? Also, if there is any missing part that I am not seeing, please inform me.

Heroku Test-Purpose App: https://erdsav-test-app.herokuapp.com/

Below is the JS code that I am tried to build on top of your code and it simply uploads the zip data and downloads it afterwards (cannot store on Heroku because of having Ephemeral filesystem) to ensure that the file is uploaded successfully;

import { Observable } from "../js/Observable.js";

document.addEventListener("DOMContentLoaded", function(event) {
    var progressBar = document.getElementById("progress"),
    fileNameSpan = document.getElementById("file_name"),
    fileSizeSpan = document.getElementById("file_size"),
    fileUploadComp = document.getElementById("file_upload"),
    loadButton = document.getElementById("upload_button"),
    displaySpan = document.getElementById("progress_display"),
    fileDetails = document.getElementById("file_details"),
    selectButton = document.getElementById("select_button"),
    formData = null;

    function hideElements(){
        fileDetails.style.display = "none";
    }

    function showElements(){
        fileDetails.style.display = "block";
    }

    function upload(payload, fileName){
        return new Observable(observer => {
            const xhr = new XMLHttpRequest();
            let progress = 0;

            /** THIS EVENT IS NOT WORKING WITH HTTPS */
            xhr.upload.onprogress = (event => {
                if (event.lengthComputable) {
                    progressBar.max = event.total;
                    progressBar.value = event.loaded;
                    progress = Math.floor((event.loaded / event.total) * 100);
                    displaySpan.innerText = progress + '%';
                    observer.next(progress);
                }
            });
            xhr.upload.onloadstart = function(e) {
              progressBar.value = 0;
              displaySpan.innerText = '0%';
            }
            xhr.upload.onloadend = function(e) {
              progressBar.value = e.loaded;
              loadButton.disabled = false;
              loadButton.innerHTML = 'Start Upload Process';
            }

            xhr.responseType = 'blob';
            xhr.open('POST', "https://erdsav-test-app.herokuapp.com/upload.php", true);  
            xhr.send(payload);
            xhr.returnedFileName = fileName;
            xhr.onload = () => {
                download(xhr.response, xhr.returnedFileName, "application/zip");
                observer.next(100);
                observer.complete();
            };
        });
    }

    function showUploadedFile(file){
        var fileName = file.name;
        var fileSize = file.size;

        fileNameSpan.innerText = fileName;
        fileSizeSpan.innerText = Math.floor(fileSize / 1000) + ' KB';
    }

    function buildFormData(file) {      
        if (formData) { 
            formData.append("file", file);
        }     

        return formData;  
    }

    hideElements(); 
    if (window.FormData) {
        formData = new FormData();
    }
    else{
        alert("FormData is not supported in this browser!");
    }

    fileUploadComp.onchange = function(){
        var file = fileUploadComp.files[0];

        if(file){
            showElements();
            showUploadedFile(file);
        }
        else{
            hideElements();
        }
    }

    selectButton.addEventListener("click", function(e){
       fileUploadComp.value = ""; 
       hideElements();    

       fileUploadComp.click();

       e.preventDefault(); 
    });

    loadButton.addEventListener("click", function(e) {
       if(fileUploadComp.files !== undefined && fileUploadComp.files.length > 0){
           this.disabled = true;
           this.innerHTML = "Uploading. Please wait...";

           var obs = upload(buildFormData(fileUploadComp.files[0]), fileUploadComp.files[0].name);
           obs.subscribe(
            function valueHandler(value){
              console.log("UPLOADING");
              if(value){
                  console.log(value);
              }
            },
            function errorHandler(err){
              console.log("THERE IS AN ERROR");
            },
            function completeHandler(){
              console.log("COMPLETE");
            }
            );
        }
        else{
            alert("No file is selected");
        }

        e.preventDefault();
    });
});

PHP side

<?php

if ($_FILES['file']['error'] != $UPLOAD_ERR_OK) {
    //writeLog($_FILES['file']['error']);
    echo 'An error occurred!'; 
    exit();
} 
else { 
   $filePath = $_FILES['file']['tmp_name'];
   $fileName = $_FILES['file']['name']; 

   if (file_exists($filePath)) {
        ob_start();
        $fileSize = readfile($filePath);
        $content = ob_get_clean();

        header('Content-Type: application/octet-stream;');
        header("Content-Disposition: attachment; filename=\"" . $fileName . "\"");
        header('Expires: 0');
        header('Pragma: no cache');
        header('Content-Length: ' . $fileSize);

        echo $content;
   }
   else{
       echo 'File is not found';
       exit();
   }
}

?>

HTML page source

<!DOCTYPE html>
<html lang="en">
    <title>ProgressBar Progress Test</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <meta name="description" content="ProgressBar Progress Test">
    <body>          
            <form method="post" enctype="multipart/form-data">
                <input type="file" id="file_upload" accept="application/zip" style="width:0px" />
                <button id="select_button">Choose File to Upload</button>
                <progress id="progress" value="0"></progress>
                <span id="progress_display"></span>
                <button type="submit" id="upload_button">Start Upload Process</button>
            </form>
            <div id="file_details" style="display: none">
                <h3>Selected File Details</h3>
                <span id="file_name"></span><br>
                <span id="file_size"></span>
            </div>
            <script type="module" src="js/Observable.js"></script>  
            <script src="js/download.js"></script>  
            <script type="module" src="js/main.js"></script>                                
    </body>
</html>

Below image is captured by slowing the network to see the current percentage while uploading process continues;

Browsers used in testing;

Firefox Developer Edition 67.0b13 (64-bit/Up-to-date)
Google Chrome 74.0.3729.108 (64-bit/Up-to-date)

这篇关于XMLHttpRequest.upload.onprogress不适用于HTTPS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆