Read the statement by Michael Teeuw here.
Weather module - creating new Provider
-
Hello! For some time now I’ve been using the (new) weather module with the default Provider (openweathermap) without any issues. I’ve started a little personal project to create a new Provider for Environment Canada - our government weather service here in Canada. They provide a very simple solution to pull an XML document for a Canadian location that contains weather info. My challenge is to create a new Provider to perform a GET against the appropriate URL and then parse out the XML elements required by the weather module.
I’m using the existing Provider code as a template, and my first task is just to ensure that I can call an Environment Canada URL and get back the XML results. I’m doing this via the fetchData instance method included in the weather module. My testing is using a URL that I know to be valid (I can access via browser and get the XML returned as expected). The URL I’m testing with is here
When fetchData is fired, I’m getting the following error thrown:
Access to XMLHttpRequest at ‘https://dd.weather.gc.ca/citypage_weather/xml/ON/s0000326_e.xml’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
I have a sense of what the error means, but not a good sense of how to fix this. My searches have found others who had a similar issue in their MM development, but any solutions do not seem applicable in this case. I think one possibility might be to configure the header for HTTP request (setRequestHeader) to include Access-Control-Allow-Origin, but I’m only guessing and the weather module Provider design does not really allow for this.
I will also say that, while I have lots of coding experience, my expertise with Javascript is definitely not extensive.
Any thoughts or advice?
-
@crazylegs This are CORS errors, it means that weather site of Canada can not be accessed via origin localhost:8080. This only occurs from browser. If you request this from Node helper it should not occur as server clients (non browser) do not check for pre flight requests. When you open it in browser it is not a api request but just GET but when you try to access it via JavaScript code it first do preflight request (OPTIONS verb) to check if you are allowed or not.
Right now weather module does the request from browser and not from node helper so this issue occurs.
possible solution is that you create a proxy api and call Canada weather api from that api and use proxy api here (which should allow CORS).
-
Thank you so much for the feedback - very much appreciated!
Your explanation makes a lot of sense and confirms (more clearly) what I’ve been reading in other places. I’ll think a bit about my options, including configuring a proxy to sit in front of the Environment Canada api or even just creating my own module that implements node_helper (although I’d prefer to leverage weather).
-
@crazylegs : would be a good idea to add node_helper in weather module and allow to have configurable option for weather provider to get the data via node helper proxy. Current code will not change much and current providers can also leverage this. If you are going to do this open an issue on GitHub and propose solution or make a pull request.
-
@ashishtank Yes I agree 100%. The optimal solution is likely to push at least some of the fetchData instance function’s responsibility into node_helper. Assuming this can be done without breaking Promise functionality, it should be invisible to current Providers. I’m going to play around with this a bit and then raise an appropriate request on github. Thanks again for your feedback and guidance!
-
you could use a proxy https://cors-anywhere.herokuapp.com/https://dd.weather.gc.ca/citypage_weather/xml/ON/s0000326_e.xmll, there is already such a line in the PullRequest merged today.
-
@karsten13 Thanks for highlighting this! I did a quick-and-dirty test in my code using this proxy and I’m now able to pull back the data from the EnvCanada provider! I will likely need to override the default fetchData function since it expects to JSON.parse the Provider data. This is not quite what I need since EnvCanada just provides an XML document to parse (JSON.parse fails…). But now I can at least start playing around some more.