Get Header Request Javascript: cURL working, fetch forbidden - javascript

i want to GET Request the Header of this link https://soundcloud.app.goo.gl/u6XXuqp3Q7Q7WXgH8 in a React App. When doing a simple request
request('https://soundcloud.app.goo.gl/u6XXuqp3Q7Q7WXgH8', function (error, response, body) {
console.error('error:', error);
console.log('body:', body);
});
I get
Access to fetch at 'https://soundcloud.app.goo.gl/u6XXuqp3Q7Q7WXgH8' from
origin 'http://localhost:3000' has been blocked by CORS policy: 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.
When using the cors-anywhere proxy
request('https://cors-anywhere.herokuapp.com/https://soundcloud.app.goo.gl/u6XXuqp3Q7Q7WXgH8', function (error, response, body) {
console.error('error:', error);
console.log('body:', body);
});
I get
request.js:150 GET https://cors-anywhere.herokuapp.com/https://soundcloud.app.goo.gl/u6XXuqp3Q7Q7WXgH8 403 (Forbidden)
But when I just cURL I get the right response
curl -s -o /dev/null -D - https://soundcloud.app.goo.gl/u6XXuqp3Q7Q7WXgH8
Can anyone explain this behaviour to me and maybe tell me how to overcome this?
Thanks!

CORS error usually comes up when you are trying to call an API from your browser directly and that API doesn't allow any other website to get the data.
There can be 2 workarounds to this problem I can think as of now -
Either you call that API from your backend code and you gather the data received from the website in backend and transfer the data on the client-side. Basically, you will be Wrapping the original API.
You can use Web Servers like NGINX and configure a specific path on the domain pointing to External API and other paths to your project. Which will help in making both the External API and Your React code on the same domain name.
Mainly your objective is to have that external API to work through your domain working along with your react code.

In browser context JS, such as a in a fetch call to an API, CORS applies. Rather with a CURL request, you are essentially running server side context, therefore CORS doesn't apply. This is why you can hit instagrams unofficial api from a server context or node.js context, but not from the same fetch call in a browser. Possible solutions:
Allow-Content-Orgin header set by the server must include the domain your page is hosted on.
Use Eletron or NodeWebkit.js for visual apps running client side with a browser (chromium) to launch your app in (mix of both browser and server context, CORS does not apply)
Run a node.js app (no browser, server context) and run your app from the terminal. (CORS does not apply)

Related

Making Get request to Yammer API works using Postman tool but not with Vue-Resource

I am trying to integrate Yammer API in my Vue.JS project, for Http calls I am using Vue-Resource plugin. While making GET Http call to get posts from Yammer it gives me following error -
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I tried postman tool and that gives successful response, but when I try to run the same thing in my Vue.JS project using Vue-Resource plugin it wont work.
The Vue.JS code snippet -
function(){
this.$http.get("https://www.yammer.com/api/v1/messages/my_feed.json").then((data)=>{
console.log(data);
});
In main.vue file i have -
Vue.http.interceptors.push((request, next) => {
request.headers.set('Authorization', 'Bearer my_yammer_token')
request.headers.set('Accept', '*/*')
next()
})
Then I tried the code snippets provided by Postman tool for jquery, that too not working.
jQuery code -
var settings = {
"url": "https://www.yammer.com/api/v1/messages/my_feed.json",
"method": "GET",
"timeout": 0,
"headers": {
"Authorization": "Bearer my_yammer_token",
"Cookie": "yamtrak_id=some_token; _session=some_token"
},
};
$.ajax(settings).done(function (response) {
console.log(response);
});
Though, I found similar questions but nothing worked for me.
I am working this to resolve from last 2 days but getting failed again and again. Please guide/help me.
A browser has higher security requirements than a request in PostMan. In a browser, you are only allowed to make XHR requests to your own current host (combination of domain + port) but not to other remote hosts. To nevertheless make a request to a remote host, you can use the browser built-in CORS. By using this, your browser makes a pre-flight request to the remote host to ask if the current page is allowed to request from that host. This is done via the Access-Control response headers. In your case, this header is probably missing or not allowing your page to access, which is why the request does not go through. Please read further into that topic.
However, in your case, using CORS probably won't be a solution for two reasons: To use CORS, the remote host must present a header which allows every requesting host (*) or your specific one. If you cannot set that setting anywhere on the remote host, it won't work. Second, it is not safe to place your authorization token into client-side JavaScript code. Everybody can just read your JS code and extract the authorization token. For that reason, you usually make the actual API call from the server-side and then pass the data to the client. You can use your own authentication/authorization against your server and then use the static authorization key on the server to request the data from the remote host. In that case, you'll never expose the authorization key to your user. Also, on the server-side, you do not have to deal with CORS as it works just like PostMan or curl as opposed to a browser.

Can fetch API from node.js but not from client [duplicate]

I tried to fetch the URL of an old website, and an error happened:
Fetch API cannot load http://xyz.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://abc' is therefore not allowed access.
If an opaque response serves your needs, set the request's mode to 'no-cors'
to fetch the resource with CORS disabled.
I understood the message, and tried to do a request that returns an opaque response:
fetch("http://xyz", {'mode': 'no-cors'})
Ok, it now works... but I can't read it. =\
What's the purpose then, of an opaque response?
Consider the case in which a service worker acts as an agnostic cache. Your only goal is serve the same resources that you would get from the network, but faster. Of course you can't ensure all the resources will be part of your origin (consider libraries served from CDNs, for instance). As the service worker has the potential of altering network responses, you need to guarantee you are not interested in the contents of the response, nor on its headers, nor even on the result. You're only interested on the response as a black box to possibly cache it and serve it faster.
This is what { mode: 'no-cors' } was made for.
Opaque responses can't be accessed by JavaScript, but you can still cache them with the Cache API and respond with them in the fetch event handler in a service worker. So they're useful for making your app offline, also for resources that you can't control (e.g. resources on a CDN that doesn't set the CORS headers).
There's also solution for Node JS app. CORS Anywhere is a NodeJS proxy which adds CORS headers to the proxied request.
The url to proxy is literally taken from the path, validated and proxied. The protocol part of the proxied URI is optional, and defaults to "http". If port 443 is specified, the protocol defaults to "https".
This package does not put any restrictions on the http methods or headers, except for cookies. Requesting user credentials is disallowed. The app can be configured to require a header for proxying a request, for example to avoid a direct visit from the browser. https://robwu.nl/cors-anywhere.html
javascript is a bit tricky getting the answer, I fixed it by getting the api from the backend and then calling it to the frontend.
public function get_typechange () {
$ url = "https://........";
$ json = file_get_contents ($url);
$ data = json_decode ($ json, true);
$ resp = json_encode ($data);
$ error = json_last_error_msg ();
return $ resp;
}

HTTP Request to external API blocked by CORS policy from every origin except localhost

I'm creating an Angular application with which I want to use the DEGIRO public API. Something is going wrong with cross-origin requests between my application and the external API.
When I run the application on localhost with ng serve my preflight requests pass the access control check perfectly. However, I run into problems when I run the application with any other origin host like [any IPv4-address]:4200 with ng serve --host [any IPv4-address]. The same problem also occurs after deploying to for example Firebase.
To communicate with the API I use the HttpClientModule with Angular as shown in the image below.
Angular HTTP POST API call
The problem I run into is described to me by the error message below.
"Access to XMLHttpRequest at 'https://trader.degiro.nl/login/secure/login' from origin
'http://192.168.178.120:4200' 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."
The main reason this error confuses me is because it doesn't happen from localhost. In the two images below the differences between the preflight request headers(localhost:4200 & 192.168.178.52:4200) are shown. Please note how the only differences are the origin and referer headers. The deployed application on Firebase is also similar like this.
Http request header (localhost)
Http request header (IPv4-address)
I've tried skipping the preflight request by adding a 'content-type': 'text/plain' header, but even the now simple request wouldn't be accepted by the CORS policy.
I have also read several somewhat similar issue's, but none of them matched my case perfectly and neither did their solutions. Next to these I have also read up a bit on CORS. I found this article very informative and helpful. https://www.html5rocks.com/en/tutorials/cors/
I can't think of any more context. I hope this post is clear and you're able to help. Thanks in any case!
Did you request a session with VWD service?
As I can see first you need to make POST request to:
https://degiro.quotecast.vwdservices.com/CORS/request_session?version=1.0.20170315&userToken=YOUR_TOKEN
And provide header:Origin: 'https://trader.degiro.nl'
and provide body: JSON.stringify({referrer: 'https://trader.degiro.nl'})
After you get the session you use that to for example: get latest bid/ask prices for a VWD issue ID
Check this package out, take look at how they managed to get it working.
Cheers :)

CORS request blocked in locally opened html file

I've started to write a HTML file which displays data with JavaScript. Since it shall be done as easy as possible I don't want to run nodejs oder any other local http server. I've just opened the HTML file in a browser (url is file:///home/visu/index.htm).
Everything is fine, till a jquery ajax request to a online API is done in the index.htm. The browser blocks the request with the message:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://x.x.x.x. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)."
How can I get rid of the problem without starting a local http server?
A possible solution is to start the browser with some "no security flags" or disable CORS with plugins, but this I've to do manually all the time so I don't like it.
When your browser will perform an AJAX request to a different server than the one hosting the current page, it first sends an OPTIONS HTTP message. In that message it sends the following header:
origin: http://my-web-server.com
And the backend server will respond with:
access-control-allow-origin: http://my-web-server.com
But, when you don't have a webserver, there is no address for your browser to put in that origin header. That's why your browser disallows you to do any AJAX request from a local file (maybe you can disable the browser's CORS security as someone mentioned in the comments, but that can put you at risk of malicious sites).
Another option
You can tell your browser to allow to connect from localhost to a backend if you change your backend to return the following header:
access-control-allow-origin: https://localhost:8888
And, you also need to tell your localhost server to serve your page in HTTPS instead of HTTP. Once both conditions are met, CORS validations won't fail.
Notice that to enable HTTPS you'll need to have a SSL cert and key, you can generate them with the following command:
openssl req -x509 -out localhost.crt -keyout localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
The source of that command and more information are found in this page from Let's Encrypt.
On Firefox, you can install this addon: https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/ to disable CORS for the respective tab. Then, any request will also work on file:/// URIs. Be careful though!
Either mock Ajax calls, or start web server with reverse proxy and HTTP rewriting configured, since I'm sure you don't want, or have not access to configure API server CORS headers.
If you don't want to mock ajax calls, then use either:
node-http-proxy
nginx - if you don't have nodejs and you don't want to install it.
Not Possible By Design
CORS are always blocked when attempted from a file on disk (web pages using the file:// protocol). There is nothing you can do to make it work from a file. It is simply impossible.
The reasoning for this is that files on disk have no real "origin" to allow the backend server to determine the validity of the request. You can have a file for an issue tracking html on the same disk as a file for a blog html. The server cannot know which html requested the data (you can even have someone else's file shared via Dropbox with embedded javascript that may attempt to access your server's data when you open it - nobody expects a hacking attempt when they simply open a plain html file!!).
This is why no browser vendor will allow you do make CORS requests from a file.
You Need a Server
To make it work you will need a HTTP server. There are lots of options for this from installing Apache/Nginx on your machine to running dev servers like webpack-dev-server or local-web-server. As long as the protocol is http:// or https:// you are allowed to make CORS requests.
Once you have a server serving your html file you can configure CORS on your backend as usual.
If you can not set it up access-control-allow-origin, you can try this.
Use "callback" function if your data is not in same domain.
And wrap your data "jsonCallback(" ... data ... ") as my example: http://www.ceducation.cz/akce-plnytext.json?short=1&callback=?
function jsonCallback(json) {
$.each(json, function(key, val) {
// your data is here
console.log('date: ' + val.date);
console.log('address: ' + val.address);
console.log('---');
});
}
$(document).ready(function() {
$.getJSON("http://www.ceducation.cz/akce-plnytext.json?short=1&callback=?", function(data) {
});
});
Working example

Reading json content from a REST API URL

I have built a REST API with Node.js Express http://localhost:3000/api/feeds with node.js and filled with data.
router.get('/api/feeds', function (req, res, next) {
documentDBConfig.getAllDocuments()
.then(() => res.json(documentDBConfig.feedsArray));
});
Now i make a static website and want to use javascript or jquery to get data from my REST API. I used this code
$.getJSON( "http://localhost:3000/api/feeds", function( data ) {
console.log(data);
});
But it keeps saying
XMLHttpRequest cannot load http://localhost:3000/api/feeds. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.
I know i'm doing it wrong, but i couldn't find the correct way. How can i get this json content with my website from my REST API (http://localhost:3000/api/feeds) ?
Edit: I don't get this warning with explorer, but i can not get the content. And now i solved the chrome problem thus i don't get this warning anymore. But i can't read the content. That is not a duplication.
Now i get this warning
Failed to load resource: the server responded with a status of 404 (Not Found)
Can you show us your REST api code so we can help you ? You need to set some headers in your backend to allow requests coming from other origins.
If you happen to be using express, this will help you. But you could have built the REST api in another way, so please provide us with more information.
This is because you are accessing a resource from another domain.
You try to access http://localhost:3000 from http://localhost:63342.
You can read more about this here https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Origin
Basically you are performing a CORS request which means you are trying to call a resource on different server. So your REST api should allow CORS requests by adding the response headers allowing the UI server resource.
Please Refer to this question if it helps

Categories