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

Add support to the window.open function for the Accept header. #7810

Open
codecando-x opened this issue Apr 11, 2022 · 8 comments
Open

Add support to the window.open function for the Accept header. #7810

codecando-x opened this issue Apr 11, 2022 · 8 comments
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: navigation

Comments

@codecando-x
Copy link

Problem:

Currently the window.open() function does not support passing in the Accept header.

Sample use case:

If i would like to make a GET request in a new browser window and ask the server via the Accept header to return mime-type text/csv instead of the default mime-type of the resource. It is not possible.

So most workarounds involve either:

  1. Changing the URL
  2. Specifying the mime-type of the expected HTTP response via a query string parameter.
  3. Make 1st HTTP request to generate the .csv file and store it either on disk or in cache. Then make a subsequent 2nd HTTP request to download it.
  4. Proxy the HTTP request on the server side from the first scenario while grabbing the expected mime-type value and making a proper GET request with the Accept header to return the correct mime-type content.

These workflows apply for any content that is dynamically generated on the server in order to be downloaded by the client.

Interest:

There seems to be quite an interest as seen via this thread on https://stackoverflow.com/questions/4325968/window-open-with-headers

Ask:

If the window.open would allow no-cors headers to be passed in. For this ask, specifically the Accept header. That would make it so a user could do all this in one call to window.open like so:

example interface could look like:
options = {};
options.url = '/reports/q12w3e4tynbvcx4567';
options.headers = {'Accept':'text/csv'};
options.mode = '_blank';
window.open(options);

Benefits and Outcomes:

Eliminating implementation complexity on both the client side, the server side, affecting performance since depending on the workarounds implementers are using it would reduce the amount of HTTP requests from 2 to 1 for millions of users who repeatedly go through these code flows to download different content across the world.

Could provide a cleaner interface to the window.open function.

@norothir
Copy link

I would add more generic support for headers. I had my own case where it would have been much simpler to add authentication details to the header to fetch documents created in the backend than creating temporary download links

@annevk annevk added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: navigation labels Apr 21, 2022
@annevk
Copy link
Member

annevk commented Apr 22, 2022

What I wrote elsewhere in regards to this:

While we could probably allow some headers to be set for navigations (essentially in line with what "no-cors" allows), it's not clear that the complexity it warrants in terms of validation and ensuring correctness of implementation is worth the effort.

If this is mainly about downloads have you considered using fetch(), URL.createObjectURL(), and <a download> instead?

@codecando-x
Copy link
Author

Thanks @annevk

It really is worth the effort since that will result in thousands+ developers not having to use workarounds to ask the server to return a specific mime-type via a standard header or as the other person on here mentioned pass in an authentication header. These are very common patterns which are hindered by this limitation. Downloads are one of the main uses of the internet they are central to exchanging data. This is pretty high impact.

The workarounds suggested and the ones in the top thread are unnecessary work for so many people. They just don't bother to ask on here because either they are not aware that they can, are so busy that they move on or don't believe that they would get heard. That doesn't mean these restrictions don't affect them.

Also by not allowing headers they are forced to shift the workload of parsing the blob and writing it locally on the client via the fetch. Which is a bit strange because they don't have the option to pass in a standard header to run the process on the server.
They are essentially forced by lack of an option to push the workload onto the client.

This seems to be a classic case of, are the browsers teams going to do the work or are they going to make everyone else do the work instead. Thousands of times, affecting many people, the potential of bugs, security issues, code spaghetti, maintenance, etc... A clean interface would go a long way in preventing all that.

Thanks for your consideration.

@norothir
Copy link

From frontend developer view, I would prefer as simple and browser standard methods possible to do downloads. Then as making the backend, I would like the API to be secure and without any temporary files and tokens. I have not followed where the browser world is going to, but downloading binary data and composing that back to a file and then saving it, is cumbersome compared that use case is to have files downloaded with authentication info. For me, I would just need to add authentication header and not to make a lot of code both to frontend and backend. I do understand that you will have different point of view.

@jimmywarting
Copy link

jimmywarting commented May 8, 2022

Hmm, why only settle for specifying headers?

We could do something more technical and more advance from the start instead...
allow opening a window using a regular Request class so you can specify method, headers, body, cache, redirect, credentials etc

Heck even opening a popup with a Response class would also be neat.

@codecando-x
Copy link
Author

@jimmywarting That would be even more awesome. I narrowed it down to my specific need.

@annevk (#7485) hinted at there being a no-cors limitation as to the headers that are allowed in the initial GET request.

@Arnoldtj
Copy link

Arnoldtj commented Mar 16, 2023

For me I'd like to call window.open with the Authorization header.

I'm trying to fetching a protected document on a server, filename.pdf, open it in a new tab, and have filename.pdf in the URL & default download name.

If I fetch the PDF in an AJAX call (passing in the Authorization header there) and call window.open on the resulting blob URL, that will confuse my end users as they are expecting filename.pdf instead of something like c6427502-eef0-4575-ba81-671c9858ec9b.pdf. When they click Download, similarly they are met with a default download name of c6427502-eef0-4575-ba81-671c9858ec9b.pdf.

This workaround almost does what I want, but it only works on Firefox, not Chrome: https://stackoverflow.com/a/52273870

@jimmywarting
Copy link

fyi, it's possible to change the hole Request / Response by using service worker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: navigation
Development

No branches or pull requests

5 participants