Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HAS PR #508] File not uploading in Edge browser, stalls at "Uploading" stage (no percentage) #507

Closed
dannya opened this issue May 26, 2020 · 4 comments · May be fixed by #508
Closed

[HAS PR #508] File not uploading in Edge browser, stalls at "Uploading" stage (no percentage) #507

dannya opened this issue May 26, 2020 · 4 comments · May be fixed by #508

Comments

@dannya
Copy link

dannya commented May 26, 2020

Describe the bug
In Microsoft Edge on Windows 10 (Microsoft EdgeHTML 18.19631, Microsoft Edge 44.19631.1.0), when trying to upload a file using FilePond, once the file is selected, the status doesn't proceed past the "Uploading" state with spinner in the UI. There are no console messages, and no AJAX request is made to my /upload endpoint.

File status stays at PROCESSING (3)

This same example works fine in Chrome and Firefox.

My project is using the Rollup bundler, but in reproducing this, I disabled treeshaking and terser minification.

For completeness, my project is loading the following polyfills in Edge (the server returns only the polyfills needed by the requesting browser):

https://cdn.polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.every,Array.prototype.filter,Array.prototype.find,Array.prototype.findIndex,Array.prototype.forEach,Array.prototype.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.some,Array.prototype.values,ArrayBuffer,atob,Blob,console,CustomEvent,DataView,Date.now,document,fetch,Function.prototype.bind,globalThis,Int8Array,JSON,Map,Math.sign,modernizr:es5object,Number.isSafeInteger,Object.assign,Object.freeze,Object.getOwnPropertyDescriptors,Object.getOwnPropertySymbols,Object.is,Object.setPrototypeOf,Object.values,Promise,requestAnimationFrame,Set,String.prototype.includes,String.prototype.padStart,String.prototype.repeat,String.prototype.trim,Symbol,Symbol.asyncIterator,Symbol.for,Symbol.iterator,Uint8Array,URL,WeakMap,WeakSet,XMLHttpRequest

Logs

I've delved into the FilePond library and found that the difference between the working Chrome browser and the not-working Edge browser can be pinpointed to this line:

// if no file loaded we'll wait for the load event
if (!(state.file instanceof Blob)) {

starting at line 228 in src/js/app/utils/createItem.js.

In Chrome, this code block is entered, since state.file is a Blob object.
In Edge, this code block is not entered, since it is a File object.

This can be resolved with the following change (using an existing utility function used elsewhere in the code for the file check):

// if no file loaded we'll wait for the load event
if (!isFile(state.file)) {

Once this code is fixed, there is a second code issue blocking uploads.

Starting at line 39 in src/js/app/utils/createFileProcessorFunction.js:

// Turn into an array of objects so no matter what the input, we can handle it the same way
(file instanceof Blob ? [{ name: null, file }] : file).forEach(item => {
    formData.append(name, item.file, item.name === null ? item.file.name : `${item.name}${item.file.name}`);
});

My understanding of the parent createFileProcessorFunction that this code resides in (based on the variable names, code structure, etc), is that this function only ever deals with a single file object (whether that be Blob, File, or something else) - therefore, the operation of a forEach in the right side of the ternary (when file is not a Blob) is not correct, since if file is a File, it does not have the forEach method.

Changing this code as follows has resolved my issue in both Edge and Chrome:

[{ name: null, file }].forEach(item => {
    formData.append(name, item.file, item.name === null ? item.file.name : `${item.name}${item.file.name}`);
});

(it can be simplified further if indeed this parent function only operates on a single file, as the forEach is redundant in this case).

To Reproduce

I am using filepond-react (though the error is happening inside the main filepond library).

Upload a file (in my case, an .xlsx file).
Error happens both on localhost server development version and online HTTPS hosted version.

Here is my React component (with added logging of every lifecycle event):

<FilePond
    allowMultiple={false}
    maxFiles={1}
    allowRevert={true}

    ref={ref => (this.pond = ref)}
    files={this.state.files}
    server='/api/upload'

    oninit={() => {
        console.log('oninit');
    }}
    onwarning={(error, file, status) => {
        console.log('onwarning', error, file, status);
    }}
    onerror={(error, file, status) => {
        console.log('onerror', error, file, status);
    }}
    onaddfilestart={(file) => {
        console.log('onaddfilestart', file);
    }}
    onaddfileprogress={(file, progress) => {
        console.log('onaddfileprogress', file, progress);
    }}
    onaddfile={(error, file) => {
        console.log('onaddfile', error, file);
    }}
    onprocessfilestart={(file) => {
        console.log('onprocessfilestart', file);
    }}
    onprocessfileprogress={(file, progress) => {
        console.log('onprocessfileprogress', file, progress);
    }}
    onprocessfileabort={(file) => {
        console.log('onprocessfileabort', file);
    }}
    onprocessfilerevert={(file) => {
        console.log('onprocessfilerevert', file);
    }}
    onpreparefile={(file, output) => {
        console.log('onpreparefile', file, output);
    }}

    onupdatefiles={(fileItems) => {
        console.log('onupdatefiles', fileItems);

        this.setState(
            {
                files: fileItems.map((fileItem) => {
                    return fileItem.file;
                }),
                uploads: pick(
                    this.state.uploads,
                    this.pond.getFiles().map(
                        (file) => file.filename
                    )
                )
            }
        );
    }}
    onprocessfile={(error, file) => {
        console.log('onprocessfile', error, file);

        if (file.status === 5) {
            // uploaded file
            try {
                const serverId = JSON.parse(file.serverId);

                this.setState(
                    (prevState) => {
                        return {
                            uploads: {
                                ...prevState.uploads,
                                [file.filename]: serverId.filename
                            }
                        }
                    }
                );

            } catch (e) {
                // TODO: do something with error?
            }
        }
    }}
/>

Expected behavior

File should be uploaded in Edge, matching the behaviour shown in browsers such as Chrome.

Stacktraces

With the above full logging, here is the different outputs:

Edge (not working)
oninit
onupdatefiles [object Object]
onaddfilestart [object Object]
onaddfile null [object Object]
onupdatefiles [object Object]
Chrome (working)
oninit
onupdatefiles [{…}]
onaddfilestart {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …}
onaddfile null {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …}
onupdatefiles [{…}]
onpreparefile {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} File {_relativePath: "", name: "google3.xlsx", lastModified: 1587694216867, lastModifiedDate: Fri Apr 24 2020 04:10:16 GMT+0200 (Central European Summer Time), webkitRelativePath: "", …}
onprocessfilestart {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …}
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.07872040476051442
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.18288578883755874
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.3299895755112473
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.4611902501121047
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.538320343665336
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.5804635906583386
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.6671355514552687
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.8444552510673365
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.8945500540967548
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.930332056260625
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 0.9486206351443808
onprocessfileprogress {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …} 1
onprocessfile null {getMetadata: ƒ, setMetadata: ƒ, abortLoad: ƒ, abortProcessing: ƒ, …}

Information about your project:

  • Your browser and the version: Microsoft EdgeHTML 18.19631, Microsoft Edge 44.19631.1.0 (vs Chrome 83 comparison)
  • Your operating system: Windows 10 (latest Insider preview)
  • FilePond version: 4.13.4 and 4.13.7
dannya added a commit to dannya/filepond that referenced this issue May 26, 2020
…ermining if a file has loaded, since in my testing, Edge is presenting a `File` object at this stage, rather than the `Blob` that Chrome etc are presenting (fixes pqina#507).

* If `createFileProcessorFunction` is presented with a file object that is not of type `Blob` (such as `File`, as seen in Edge browser), it attempts to iterate over it using `forEach` as if it were an iterable object, however `File` objects do not have a `forEach` method. Resolve this by treating all file object input into this function as though they are a singular, non-iterable object (fixes pqina#507).

* Fix comment typo.
@dannya dannya changed the title File not uploading in Edge browser, stalls at "Uploading" stage (no percentage) [HAS PR #508] File not uploading in Edge browser, stalls at "Uploading" stage (no percentage) May 26, 2020
@dannya
Copy link
Author

dannya commented May 26, 2020

Interestingly, the first example upload form at https://pqina.nl/filepond/#examples does work for me in Edge, so there is obviously some issue somewhere between however that example is configured and build, and my own React project.

I think my changes in PR #508 are still worthy of consideration regardless.

@rikschennink
Copy link
Collaborator

@dannya Thanks so much for your effort, I will look into this as soon as possible.

@rikschennink
Copy link
Collaborator

@dannya It looks like the Blob polyfill is causing the problem. If you remove it from the list everything works as expected.

@dannya
Copy link
Author

dannya commented Jun 9, 2020

Thanks for your investigation into this @rikschennink, I can confirm that removing the Blob polyfill resolves the issue.

That said, I think the changes in my PR (aside from the comment typo and console.log) are still relevant, with the key change being a simplification to using the existing isFile utility function, but you can use your own judgement on this.

@dannya dannya closed this as completed Jun 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants