CORS Support for API Use
-
Hi.
Thanks in advance for any help with this API usage concern.
I am a new user of NodeBB. I've gotten the latest version of NodeBB running in my development environment. Amongst other things, I'd like to leverage the NodeBB api in my web application.
Though I can curl the cors api (e.g. /api/categories), my web app fails with the following message:
I've searched online for others that have struggled with this.
CORS Support by CynicalBusiness · Pull Request #3899 · NodeBB/NodeBB
Requests to *.rss and /api/* done by an XMLHttpRequest with jQuery's $.ajax or AngularJS's $http are being rejected due to missing CORS headers. I've added the basics for the Access-Control-Allow-*...
GitHub (github.com)
I've also searched the config.json documentation for a "cors" option that I might configure.
I've not found anything that helps me get past this.
Is there a server side configuration that I can change?
Alternatively if I need to make a change in my web application client code, what does that change look like?
My "axios based client code" looks as follows:
import _ from "lodash"; import axios from "axios"; const urlencode = "application/x-www-form-urlencoded"; async function GetDataFromNodeBB(options, data) { try { var url = options.hostname + ":" + options.port + options.path; if (_.get(options, "headers.Content-Type") === urlencode) { data = new URLSearchParams(data).toString(); } var resp; if (options.method === "POST") { resp = await axios.post(url, data, options); } else if (options.method === "PUT") { resp = await axios.put(url, data, options); } else if (options.method === "DELETE") { resp = await axios.delete(url, options); } else if (options.method === "GET") { console.log("GET!!!", url) if (data === undefined) { resp = await axios.get(url, options); } else { resp = await axios.get(url, { ...options, params: data }); } console.log("GOT???", resp) } if (resp.statusCode < 200 || resp.statusCode >= 300) { console.log("Invalid credentials:", resp); return false; } return resp.data; } catch (err) { console.error("Error with connection to Keycloak:", err); return false; } } export function reqGetDiscussionCategories(token, serviceDefinition) { var data = { token_type_hint: "requesting_party_token", client_id: "undefined", access_token: token, }; var options = { hostname: serviceDefinition.NODEBB_URL, port: serviceDefinition.NODEBB_PORT, path: "/api/categories", method: "GET", headers: { "Content-Type": "application/x-www-form-urlencoded", }, }; return new Promise(async (resolve, reject) => { try { var result = await GetDataFromNodeBB(options); if (result === false) { reject({ error: "Invalid token" }); } resolve({ nodebbResponse: result }); } catch (err) { console.log("Error:", err); reject({ error: err }); } }); }
-
As an aside, I've also tried to add this in the ACP:
-
Hi @David-Sargrad, have you tried adding a specific domain to that list? While the
*
value is a valid header, I am not certain whether that value there would be considered valid. -
Thanks Guys. I'll try that. Right now I'm on localhost, so presumably:
http://localhostshould work?
-
I've tried both http://localhost
However I still get the same problem.
I can browse to this URL however..
-
Chrome does not support CORS for
localhost
: https://stackoverflow.com/questions/10883211/why-does-my-http-localhost-cors-origin-not-work -
@julian I'm not sure I understand the question. I am on my development machine. I am running a local instance of nodebb on that same machine.
@PitaJ I did see some interesting options listed at the location you linked. I'll try them.
I would have thought that this is something that many NodeBB developers (those that want to use the NodeBB API) would have seen and learned to address in a standard way.
-
Ok. I find this interesting, and it better helps me to understand @julian
https://stackoverflow.com/questions/45975135/access-control-origin-header-error-using-axiosThe "site" that I am calling from is likely my "react app" which is running at http://localhost:3000
Of specific interest is this persons description
https://stackoverflow.com/a/64137023However this also explains why I thought "*" should work as in the following:
app.get('/hello', function (req, res) { res.header("Access-Control-Allow-Origin", "*"); res.send('Hello World'); })
I've developed such node express services before, and have always used this practice when I want to allow cross origin requests on the localhost.
-
I also like the "nginx" option. I may try this eventually.
In fact the example shown in the link above is exactly the scenario I am using with NodeBB's API.
-
Yay!! It worked when I used the ACP to set the Access-Control-Allow-Origin field to http://localhost:3000.
I would recommend looking at allowing "*". This is a common CORs practice, particularly in a development environment.