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

IE8 does not use the headers supplied in upload config #111

Closed
peteorpeter opened this issue Jan 23, 2014 · 13 comments
Closed

IE8 does not use the headers supplied in upload config #111

peteorpeter opened this issue Jan 23, 2014 · 13 comments
Labels

Comments

@peteorpeter
Copy link

If you specify headers in the upload config object, like this:

scope.fileSelected = function (file) {
  scope.upload = $upload.upload({
    method: 'POST',
    url: scope.requestResponseModel.url,
    file: file,
    headers: {
        'Content-Type': 'multipart/form-data',
        'Accept': '*/*'
     }
  })

...they are used by modern browsers. But IE8 with the flash shim always sends the same request headers regardless - it appears to be hard-coded, though I haven't dug into that yet.

In my particular case, the 'Accept: text/*' that IE8 uses in requests is causing my server to throw 406 errors because the response is configured to return the "application/json" content-type.

Thanks for the very useful module and please let me know if there's something I can do to help troubleshoot!

@peteorpeter
Copy link
Author

Looks like this may be a limitation of the FileAPI flash shim:

"Additional request headers, HTML5 only."
https://github.com/mailru/FileAPI#headersobject

In which case I'm not sure there's much to be done, except perhaps document this limitation. I'll wait for responses here, but will work on a server-side workaround in the meantime.

@danialfarid
Copy link
Owner

Thanks for figuring this out.
I have opened an issue on FileAPI github here https://github.com/mailru/FileAPI/issues/189
If that could be fixed then the request headers for Flash will be supported.

@danialfarid
Copy link
Owner

Seems like that's just an error in the FileAPI docs and flash should support custom headers.

@peteorpeter
Copy link
Author

I'm not 100% on FileAPI being the actual limitation here, but I do know that setting arbitrary headers works on modern browsers but not IE8 with the shims in place. Could there be a config issue on my end?

@danialfarid
Copy link
Owner

Do you use CORS?

@peteorpeter
Copy link
Author

No CORS. It looks like there's another comment on that issue you opened that might explain it - points to http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html#upload()

@peteorpeter
Copy link
Author

Finally found the new location of the "link-to-comment" feature in github! Here's the comment I was referring to: https://github.com/mailru/FileAPI/issues/189#issuecomment-33559283

@blaise-io
Copy link

Headers are supported in FileAPI, my file upload works when I call FileAPI.upload() directly.
But when I call $upload.upload (which wraps the call to FileAPI.upload), headers are getting stripped.

(My request header must contain a csrf token)

@danialfarid
Copy link
Owner

FileAPI doesn't support custom headers for Flash (IE8-9)
Follow this thread: https://github.com/mailru/FileAPI/issues/189

@mlarcher
Copy link

Hi Danial,
I too have a problem with this limitation, as I'm trying to use your lib to send files to an API which needs an "Authorization" header.
I've read the related links here and on the FileAPI repository, and I'm not clear on my options.

Let me sum it up to make things clearer :
If I understand correctly, angular-file-upload Flash fallback is based on https://github.com/mailru/FileAPI/ which relies on the AS3 "FileReference" object.
FileReference is quite limited and won't allow for most common headers (cf http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/URLRequestHeader.html ).
You spotted some workaround on stackoverflow ( http://stackoverflow.com/questions/509219/flex-3-how-to-support-http-authentication-urlrequest/509433#509433 and http://stackoverflow.com/questions/509219/flex-3-how-to-support-http-authentication-urlrequest/12933681#12933681 ) but those "don't suit" the creator of the flash FileAPI project (I wish he gave more information on the matter, but he didn't).

So, my questions are :

  • do you think someone could make a fork of the FileAPI project that would fix this problem ?
  • would it be possible to conditionnally disable the flash fallback in angular-file-upload ? We could then handle things differently for IE8/9 than for other browsers (i.e. make a basic file upload with no progress bar but with the expected headers)
  • do you have any other workaround to suggest for such a situation ?

@danialfarid
Copy link
Owner

You are right.

  1. FileAPI could be forked to fix that issue but who knows if it would ever happen.
  2. Yes it is possible but still since IE8/9 won't let you access the file object through javascript you cannot send an XMLHttpRequest with the file in it just by using javascript. Basic file upload with form submit won't allow custom headers either. So the only way I could think would be to find another Flash plugin that would let custom headers, so far other options I investigated have the same limitation, or to use Silverlight which probably needs a manual installation on the client machine and not sure how stable and reliable it is.
  3. for the other workarounds:
  • Some servers allow the authorization headers to be sent as request parameters as a workaround for upload or you could write a custom request filter on your server to read the auth request parameters and add them to the header before it is processed by your authorization filter.
  • You could customize your server code to bypass the authorization and upload the file to a tmp folder on the server with a unique ID, then return the id to the client and that ID could be used to send another normal ajax request with authorization headers with other related data. Then on the server side you can find the file on the server from the given ID. This way even if unauthorized users upload files it would just sit in the tmp folder and won't be linked to anything and will be deleted by OS or your scheduled job.

@mlarcher
Copy link

Thanks for the quick and thorough reply. We'll weigh our options in the light of those informations.

We are considering creating a fork of the FileAPI project, as we have talented flash devs in our company and this seems the better option.
The params-in-query is an interesting approach, we might resort to that if time runs short.
For the last suggestion, I'm not keen on it, as it would imply allowing non recognized users to send arbitrary content on the hard drive and potentially filling it up.

Be sure that if we end up making an alternative version of the FileAPI project, we'll either propose a PR or make the fork publicly available.

@mlarcher
Copy link

After a bit of digging with our flash devs, it seems we are indeed stuck on the FileAPI side.

By design, Adobe prevents the use of custom headers when using FileReference.upload().
This can be seen in their doc on http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html#upload%28%29 :

Parameters
request:URLRequest — The URLRequest object. The url property of the URLRequest object should contain the URL of the file to download to the local computer. If this parameter is null, an exception is thrown. The requestHeaders property of the URLRequest object is ignored; custom HTTP request headers are not supported in uploads or downloads. To send POST or GET parameters to the server, set the value of URLRequest.data to your parameters, and set URLRequest.method to either URLRequestMethod.POST or URLRequestMethod.GET.

We're gonna dig a bit more into it, but the most probable scenario is that anything coming from a FileReference (i.e. access to user file system) will only be sendable through FileReference.upload(), so without any way to tweak the headers.

Another issue related to the header tweaking is that the "Accept" header sent by the FileReference.upload() method has a "text/*" value ( cf #121 ). If your server is only sending "application/json" as a result, it may deny the request. If the "no tweak in headers" rule sticks, that means this problem can only be handled serverside.

For now, we've decided to passed the authorization token through the url query and let the server return text/json if the request is text/*. text/json is not the official content-type, but it's a quite common one anyhow so we don't expect it to raise any problem.

With this setup, we're now able to send a file to the server. It works alright in IE9, we're still trying to figure out why the upload doesn't start in IE8 -> #281

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants