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

angular-file-upload-shim does not work correctly on Chrome - Failed to execute 'setRequestHeader' on 'XMLHttpRequest' #579

Closed
nicops opened this issue Feb 24, 2015 · 14 comments

Comments

@nicops
Copy link

nicops commented Feb 24, 2015

When I try to upload a file, I get this error:

Error: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': 'function (xhr) {
            if (!xhr) return;
            config.__XHR = xhr;
            config.xhrFn && config.xhrFn(xhr);
            xhr.upload.addEventListener('progress', function(e) {
                e.config = config;
                deferred.notify ? deferred.notify(e) : promise.progress_fn && $timeout(function(){promise.progress_fn(e)});
            }, false);
            //fix for firefox not firing upload progress end, also IE8-9
            xhr.upload.addEventListener('load', function(e) {
                if (e.lengthComputable) {
                    e.config = config;
                    deferred.notify ? deferred.notify(e) : promise.progress_fn && $timeout(function(){promise.progress_fn(e)});
                }
            }, false);
        }' is not a valid HTTP header field value.

What I figured out is that $upload sets a fake header called __setXHR_ and angular-file-upload-shim patches some methods to manage the fake header here:

patchXHR('setRequestHeader', function(orig) {
    return function(header, value) {
        if (header === '__setXHR_') {
            initializeUploadListener(this);
            var val = value(this);
            // fix for angular < 1.2.0
            if (val instanceof Function) {
                val(this);
            }
        } else {
            this.__requestHeaders = this.__requestHeaders || {};
            this.__requestHeaders[header] = value;
            orig.apply(this, arguments);
        }
    }
});

The problem is that angular-file-upload-shim conditionally executes most of its code:

 if ((window.XMLHttpRequest && !window.FormData) || (window.FileAPI && FileAPI.forceLoad))

And at least in my browser (Chrome 40.0.2214.93 for Linux), window.FormData is set, and window.FileAPI is not, so the condition isn't met.

In summary:

  • The fake header is set
  • The patched XHR function that would process the fake header is not set.
  • The core javascript libraries cannot process the fake header and everything stops working

Versions:

  • angular 1.3.12
  • ng-file-upload 3.0.7
@danialfarid
Copy link
Owner

Can you post your code here or create a jsfiddle from the sample jsfiddle on readme file.

@cmartin81
Copy link

+1

@danialfarid
Copy link
Owner

You guys need to create a jsfiddle or a running code to show the error. As long as the demo page is working you probably have an error in your setup of the library or conflicting libraries.

@cmartin81
Copy link

Thanks for the update. I fixed the problem by rearrange the javascript files.

@larjohn
Copy link

larjohn commented Apr 19, 2015

This does not work for me when I use it with pace.js. XMLHttpRequest gets replaced by pace, so the setRequestHeaders gets back to its native implementation...

@danialfarid
Copy link
Owner

You can probably fix it by rearranging the scripts. Make the pace load first and then angular and then angular-file-upload. or play with the order.

@joshribakoff
Copy link

I had the same issue start occurring randomly & it turned out to be due to moving pace.js to load before this lib. I fixed it by removing pace.js

@pdemilly
Copy link

pdemilly commented Aug 7, 2015

Got same issue. Removing pace.js seems to fix it, however would be nice to support it

@jburcsik
Copy link

+1 for same issue and removing pace (not changing it's position in the load) fixed the issue.

@danialfarid
Copy link
Owner

If you guys want this to be fixed faster please create a jsfiddle showing the error: steps to reproduce.

@TheFabio
Copy link

TheFabio commented May 7, 2016

Loading "ng-file-upload.js" before loading "pace.js" fixed the issue for me.

@flexchar
Copy link

flexchar commented Aug 8, 2016

Same here, have been experiencing error: "XMLHttpRequest cannot load https://foreign_domain.tld/. Request header field _setXHR is not allowed by Access-Control-Allow-Headers in preflight response."
and moving pace.min.js after this library fixed it. Thanks.

@Dufgui
Copy link

Dufgui commented Oct 20, 2016

I have the same problem and my dep are injected via gulp so...i create a small patch as describe in #832

Bower : pace-ng-file-upload-inlinepatch 0.0.6
https://github.com/Dufgui/pace-ng-file-upload-patch

@pradt
Copy link

pradt commented Nov 2, 2016

Hi, how did you guys work out that it is was Pace.js ? I'm not using pace.js but I'm receiving this error, and trying to work out what is the conflict.

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

No branches or pull requests