1
<a href="www.myfile.json" download>download file</a>

"www.myfile.json" is a link to a json file. My goal is when user clicks "download file", the json file is downloaded automatically. However, with above code, when I click "download file", it opens the json file in browswer for me. I would like to know what I am doing wrong here.

I have tried the solution in this link(Chrome 65 blocks cross-origin <a download>. Client-side workaround to force download?), but I got Access to fetch at 'XXXXX' from origin 'XXXX' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. However, I do set 'Access-Control-Allow-Origin':'*' in my request header. I am not able to modify anything on server side. What should be the right way to do for me?

My header looks like below:

headers: new Headers({
                 'Origin': location.origin,
                 'Access-Control-Allow-Origin': '*',
                 }),
                 mode: 'cors'
            })

Besides, I also tried set mode: 'no-cors', but it does not work.

bunny
  • 1,797
  • 8
  • 29
  • 58
  • Possible duplicate of [Force external download url](https://stackoverflow.com/questions/13451720/force-external-download-url) – Tyr Apr 09 '19 at 22:16
  • in what browser have you tried this? Check https://caniuse.com/#feat=download to see if the feature is supported in your browser. – ADyson Apr 09 '19 at 22:25
  • I tried with chrome and it should work, but it did not. – bunny Apr 09 '19 at 22:29
  • 1
    Bear in mind that if the file in your hyperlink is not on the same domain as the webpage where the link is located, some browsers will ignore the "download" attribute. This is intended as a security feature, I believe. Chrome is one of those browsers - see https://bugs.chromium.org/p/chromium/issues/detail?id=714373 – ADyson Apr 09 '19 at 22:29
  • 1
    See also https://stackoverflow.com/questions/49474775/chrome-65-blocks-cross-origin-a-download-client-side-workaround-to-force-down – ADyson Apr 09 '19 at 22:31
  • I am currently working in local environment and the link is likely not the same domain. – bunny Apr 09 '19 at 22:34
  • "likely"? You surely must know already if it is the same domain or not? For example if you're running the site on `http://localhost` and the file is at `http://www.example.com/myfile.json` then clearly they are on different domains. However if the file is at `http://localhost/files/myfile.json` for example, then they are on the same domain. – ADyson Apr 09 '19 at 22:37
  • Yes, they are not in the same domain. I am sorry. – bunny Apr 09 '19 at 22:48
  • 1
  • Thanks for the link! I will take a look. I also tried to download using firefox and edge and get the same experience. – bunny Apr 09 '19 at 22:53
  • Yes, Firefox also blocks the attribute on cross-origin links in the same way. IE doesn't support the attribute at all, and mobile support is patchy (see the caniuse link above), so overall I wouldn't rely on the download attribute – ADyson Apr 10 '19 at 05:52
  • The solution does not for work me. I got Access to fetch at 'XXXXX' from origin 'XXXX' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. However, I do set 'Access-Control-Allow-Origin':'*' in my request header. – bunny Apr 10 '19 at 22:59

1 Answers1

1

The Access-Control-Allow-Origin: * header needs to be in the response, not the request. You won't be able to read the response data without cooperation from the server.

So find a more cooperative server.

There's a simple CORS proxy that will download any URL you give it, tack on the Access-Control-Allow-Origin header, and send it back to you. If you're comfortable with a third party seeing the contents of your JSON file, you can change the fetch line in the linked solution from

  fetch(url, {

to

  fetch(`https://bypasscors.herokuapp.com/api/?url=${encodeURIComponent(url)}`, {
AuxTaco
  • 4,883
  • 1
  • 12
  • 27
  • I found we cannot use an unknown proxy. – bunny Apr 12 '19 at 17:32
  • In that case, you'll have to build your own server-side script that reads the file (with e.g., [`readfile`](https://www.php.net/manual/en/function.readfile.php) in PHP, [Requests](https://requests.readthedocs.io/en/master/) in Python, [`http.get`](https://nodejs.org/api/http.html#http_http_get_url_options_callback) in Node.js) and echoes it back in the response. And when you do that, you can set the `Content-Disposition: attachment` header (again, in the response) and not worry about `download` and all the JavaScript. – AuxTaco Apr 13 '19 at 00:25
  • When you say "not worry about download and all the JavaScript", do you mean I still need download attribute in my a tag, but no need fetch api call? – bunny Apr 16 '19 at 18:23
  • What I have tried is that set the Content-Disposition: attachment in header in response. In html, I have , but it still opens the request page for me not download any thing. Did I miss anything here? – bunny Apr 16 '19 at 18:36
  • If you don't control www.example.com, you aren't setting any headers in the response. Response headers come from the server; they can't be set from client-side code. If you do control www.example.com, `Content-Disposition: attachment` *should* start the download with just ``. I don't know why it wouldn't. – AuxTaco Apr 16 '19 at 20:36
  • I see. Thanks for the help! – bunny Apr 16 '19 at 20:58