Regular webpages opened in Chrome don’t get access to the file system, while obsidian plugins can use the javascript fs
module for local files. I thought that something similar is available for web requests.
If you are okay with your plugin only working in the desktop you can use the package node-fetch. GitHub - node-fetch/node-fetch: A light-weight module that brings the Fetch API to Node.js node’s libraries bypass cors restrictions but are only available in the desktop apps.
Hi,
I have a similar problem. I want to implement a CalDav Client Plugin and get the same error.
I try to implement a middleware with express and the cores package, but it doesn’t work. Can someone give me please a code example, a tutorial or a link to the Glichßs express server?
Thanks
Kantiran
You can overcome this by using node.js’ http/https module instead of fetch (or use a convenience module like request). It doesn’t have the same limitations.
require('request')('http://example.com/', (error, response, body) => {
console.log(JSON.parse(body));
});
I want to get google books API data, but I’m running into this same CORs policy issue. @intellectronica, I don’t think your solution works for me, at least while trying in the dev console. Some people might have luck with this article. I haven’t got it to work yet.
I’m not working on a plugin, but I’m using a dataviewJS code block to download image data.
Hello @mjduck,
This may interest you !
It’s a script to be used inside Quickadd plugin to fetch book data from Google Books API, and then automatically create a note from a template.
You can check line 183
of the script how the request is made using request
. I have not encountered CORs issues with that function.
The author of Quickadd plugin made a script to fetch movie data using OMDB API (using the same request
function) which helped me a lot to write this Google Books API script.
In plugin you should import requestUrl
function provided by obsidian
package, see the declaration at obsidian-api/obsidian.d.ts at c01fc3074deeb3dfc6ee02546d113b448735b294 · obsidianmd/obsidian-api · GitHub
Is this usable from within a Templater template or DataviewJS? That is, is it usable within arbitrary JS executing within an Obsidian plugin?
Asking as something of a node/TS newbie but experienced developer. I assume that this depends on what sort of library search paths are available from within the environment provided at runtime by these respective plugins?
DataviewJS and Templater have access to most functions.
These included.
You can check by opening the Console in the Developer tools, and see if it shows up.
The one thing they can’t do is anything related to event handling.
So how would a basic dataviewjs codeblock look that incorporates such a requestUrl
call? How would the response be handled inside such a dataviewjs codeblock?
Imagine the request I want to use returns a JSON string which contains data/numbers I want to see in a table (or even visualize with the Obsidian Charts plugin)?
As a quick example:
One of my notes has a weather forecast embedded that uses DVJS
Here is a part of it
const headers = {
"Authorization": "Bearer whatever"
}
const forecast = await requestUrl({url: "https://weatherapi/forecast", headers})
dv.table(["Datum", "Icon", "Beschreibung", "Min", "Max", "Regen", "Luftfeuchtigkeit"], forecast.json.map(day => {
return [
dv.date(day.date).day + ".",
"![icon|50](" + day.icon + ")",
day.description,
day.temperature_min + "°C",
day.temperature_max + "°C",
day.probability_of_precipitation + "%",
day.humidity + "%"
]}))
The data returned by that API looks like this:
[
{
"date": "2022-06-26T11:00:00Z",
"sunrise": "2022-06-26T02:55:38Z",
"sunset": "2022-06-26T20:00:30Z",
"temperature_day": 19.19,
"temperature_night": 18.76,
"temperature_min": 18.3,
"temperature_max": 21.55,
"feels_like_day": 19.38,
"feels_like_night": 18.65,
"pressure": 1016,
"humidity": 85,
"dew_point": 16.65,
"uvi": 6.26,
"clouds": 100,
"visibility": 0,
"wind_speed": 7.47,
"wind_degree": 0,
"description": "Leichter Regen",
"icon": "icon_url_here",
"probability_of_precipitation": 0.5
},
....
]
I am using requestUrl to avoid this issue but it seems that I am getting an issue anyway. Error thrown:
{
“status”:400,
“headers”:{
“vary”:“Origin, Access-Control-Request-Method, Access-Control-Request-Headers”,
“x-content-type-options”:“nosniff”,
“x-frame-options”:“DENY”,
“x-xss-protection”:“1; mode=block”
}
}
Anyone got any ideas?
You’d have to post the request code for anyone to give any hints.
HTTP status 400 “indicates that the server cannot or will not process the request due to something that is perceived to be a client error (for example, malformed request syntax”.
So it sounds like the code to create the request is invalid.
I do apologise, first time posting here … not something I am used to doing
Here is the code, it’s a pretty simple call:
const options: RequestUrlParam = {
url: url,
method: 'POST',
headers: {
'X-Api-Key': this.settings.apiToken,
'Content-Type': 'application/json'
},
body: json
}
var response: RequestUrlResponse;
try
{
response = await requestUrl(options);
return response.text;
}
catch(e) {
console.log(JSON.stringify(e);
}
I captured the actual request and sent it to the server (headers and all) using Postman (just to check that what I am sending is valid) and the server accepted it no problem.
I can’t actually see anything of my call appearing in the Network tab of Developer Tools. I can see other traffic but nothing on this call. All seems a bit weird but I am very new to this so hoping someone can spot something obvious.
It might also be worth (or not) pointing out that it is throwing an error rather than returning the status via the response.
You’ll need to stringify that JSON first I believe. Postman is probably handling that for you.
Is there a current best practice for making HTTP requests from plugins avoiding CORS ? I haven’t found any official documentation on it and at least one of the packages mentioned as a possibility is now deprecated. This seems like it would be common enough of a desire that there would be some documentation.
You can use this function from the official docs:
Request a URL using HTTP/HTTPS, without any CORS restrictions.
Thanks! I dunno how that didn’t show up in my searching. That is exactly what I am looking for : )