0

I am trying to get the csv data from a url from the nrel developer website. Unfortunately I can't work with json data because it will send it to the email, while the csv file is immediate. I could achieve this using vba using the following:

With req
    .Open "GET", parsedUrl, False
    .SetRequestHeader "Content-Type", "text/csv;"
    .Send
End With

result = Split(req.responseText, Chr(10))
'do work with result

However, working with javascript and the excel addins documentation I am not able to store the csv data on a variable. I tried the following code

const res = await fetch(tmyUrl, {
    method: "GET",
    headers: {
      "Content-Type": "text/csv;",
    },
  });
  if (!res.ok) throw new Error("There was a problem trying to get the the weather data.");

But this gives me the following error: has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I also tried adding the following:

mode: "no-cors"

But the res.ok is false and the body seems to be empty. It takes a little time to process this request, so I know it is doing something in the background. I also could trigger the download using downloadjs but I don't need to download, I just need to temporary store the data in a variable.

Any help or advice please.

1 Answers1

0

I also tried adding [mode: "no-cors"] but... the body seems to be empty.

This is precisely because you're calling the endpoint with mode: no-cors. This behavior is well-documented, and discussed at length in this SO thread. From the linked MDN page (emphasis mine):

no-cors — Prevents the method from being anything other than HEAD, GET or POST, and the headers from being anything other than simple headers. If any ServiceWorkers intercept these requests, they may not add or override any headers except for those that are simple headers. In addition, JavaScript may not access any properties of the resulting Response. This ensures that ServiceWorkers do not affect the semantics of the Web and prevents security and privacy issues arising from leaking data across domains.


The reason you're seeing CORS errors in the first place is that the server that's responding to your request has deliberately been configured this way to prevent these types of requests on its resources. You can bypass this by making the request to your own server (which allows CORS), which can then proxy the ultimate request to the service and return the response to your client. There used to be several prominent drop-in services that provided this functionality, but most have gone by the wayside due to service abuse (CORS Anywhere and Whatever Origin, to name two).

There still exists one service that appears to still proxy these types of requests - All Origins. Drop in your URL according to their documentation to effectively bypass this restriction:

const res = await fetch(`https://allorigins.win/get?url=${encodeURIComponent(tmyUrl)}`, {
    method: "GET",
    headers: {
      "Content-Type": "text/csv;",
    },
});

Be forewarned, you really, really need to trust this service to use this in any project. By routing your requests through their service, you are implicitly allowing them to snoop on your traffic uninhibited and potentially return malicious content to your clients. It's a much better idea to do this on your own server that you control.

esqew
  • 42,425
  • 27
  • 92
  • 132