I have a question about cryptomarket Binance.
They have public api which I though I could use in angular to create trading app.
But I have some troubles.
Using that link in chrome I get json result.
https://api.binance.com/api/v1/exchangeInfo
But using with angular 4 httpClient:
this.http.get('https://api.binance.com/api/v1/exchangeInfo').subscribe(res => console.log(res));
I have error: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at api.binance.com/api/v1/exchangeInfo. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)
It doesn't work. I don't get it, why I can't use that API in angular app?https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md
What should I do?
Should I set headers like that:
getMarkets() {
const headers = new HttpHeaders();
headers.set('Content-Type', 'application/json');
headers.set('Accept', 'application/json');
headers.set('Access-Control-Allow-Headers', 'Content-Type');
headers.set('Access-Control-Allow-Origin', '*');
const path = 'https://api.binance.com/api/v1/exchangeInfo';
return this.http.get(path, {headers: headers});
}
Thanks in advance
You can't quite use it directly like that, Binance API does not set CORS headers, so Chrome and all major browsers will block the requests.
There is a bit more to it, but essentially, the api servers that need to enable support for CORS should set Access-Control-Allow-Origin to be * or a single domain www.example.com, this allows the browsers to prevent malicious code on a site to call and read the response of some data from other site you might be logged on to ( eg: bank info )
You can read more about it here
One possible solution is to have your own server that proxies calls to binance
Another solution if you're testing things out is to use a CORS enabling extension like this one
Update: You can also use the websocket API if that satisfies your data needs docs
Update 2: Here's a good stackoverflow question on cors
Side note: If your bank's API server sets the Access-Control-Allow-Origin to * then change banks :)
Try this simple request without headers.
this.http.get('https://api.binance.com/api/v1/exchangeInfo').subscribe(data => {
this.results = data;
});
}
It work for me
HttpHeaders is immutable. So you must write
const headers = new HttpHeaders().
set('Content-Type', 'application/json').
set('Accept', 'application/json').
set('Access-Control-Allow-Headers', 'Content-Type').
set('Access-Control-Allow-Origin', '*');
or
const headers = new HttpHeaders(
{
Content-Type:'application/json'),
Accept:'application/json'),
Access-Control-Allow-Headers:'Content-Type'),
Access-Control-Allow-Origin:'*')
})
Related
I've been trying to integrate Amazon pay as a payment method for customers on my website but am running into issues with some of what's detailed in the documentation. I'm hoping to better understand the request headers that are to be associated with a call to the amazon pay api.
I'm making a request to 'https://pay-api.amazon.com/v2/checkoutSessions/checkoutSessionId' and receiving a CORS policy error.
Access to fetch at 'https://pay-api.amazon.com/v2/checkoutSessions/d9b4418d-0c6f-4085-8c37-08bef6da6807' from origin 'http://localhost:3000' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Here is the fetch request where I am trying to make the request
fetch(`https://pay-api.amazon.com/v2/checkoutSessions/${this.$route.query.amazonCheckoutSessionId}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'authorization': 'Px2e5oHhQZ88vVhc0DO%2FsShHj8MDDg%3DEXAMPLESIGNATURE',
'x-amz-pay-date': `${new Date()}`
}
})
this.$route.query.amazonCheckoutSessionId references the returned url extension after the user creates a checkout session using the amazon pay button.
The documentation outlines a request should be made as follows
curl "https://pay-api.amazon.com/:version/checkoutSessions/:checkoutSessionId"
-X GET
-H "authorization:Px2e5oHhQZ88vVhc0DO%2FsShHj8MDDg%3DEXAMPLESIGNATURE"
-H "x-amz-pay-date:20201012T235046Z"
Can someone please explain where I'm supposed to get the authorization string and its format? Also, is there a way to easily format a date string into the format displayed in the documentation? Or does the date string format not matter?
I have searched quite extensively through the stack overflow posts associated with Amazon pay (of which there are few) as well as searching other Amazon and AWS documentation for elaboration on how to format the auth string. Unfortunately, I can't seem to find an answer. I have also tried passing my button signature as my authorization string, but that didn't seem to help.
Thank you for any help you can give.
There are two parts to your problem:
The API is not designed to listen to Browser JS (AJAX) requests as in your sample. The CORS restriction is in place to prevent this. Rather this part of the process is to be done on the server side
To use the API, I would strongly recommend using one of the SDKs (https://pay.amazon.co.uk/help/201212390?ld=APUKLPADirect). You will notice in the docs (https://developer.amazon.com/docs/amazon-pay-checkout/add-the-amazon-pay-button.html), that they always have the code samples for all four offered SDKs. So it is much easier to follow those instructions.
The Amazon Pay API's do not support direct client side requests, so you'll need to make those requests server side. That's why you're seeing a CORS error.
You can find a detailed walk through on the signature generation required to sign each of the API requests here: https://developer.amazon.com/docs/amazon-pay-api-v2/signing-requests.html
You should be able to leverage the Amazon Pay Node.js SDK, which will save quite a bit of coding - https://developer.amazon.com/docs/amazon-pay-checkout/get-set-up-for-integration.html#nodejstab
I'd also recommend using the developer scratchpad as a way to sanity check your work and get tips on required code, since it will make requests for you and generate code snippets!
https://pay-api.amazon.com/tools/scratchpad/index.html
You can invoke the getCheckoutSession method from the SDK (.NET, Java, Node.js, PHP). The curl example that Amazon provides is only if you are developing a solution without using the SDK.
Here is an example from the Node.js SDK README.md.
npm i #amazonpay/amazon-pay-api-sdk-nodejs
const fs = require('fs');
const uuidv4 = require('uuid/v4');
const Client = require('#amazonpay/amazon-pay-api-sdk-nodejs');
const config = {
publicKeyId: 'ABC123DEF456XYZ',
privateKey: fs.readFileSync('path/to/private-key/private.pem'),
region: 'us',
sandbox: true
};
const headers = {
'x-amz-pay-idempotency-key': uuidv4().toString().replace(/-/g, '')
};
const checkoutSessionId = 00000000-0000-0000-0000-000000000000;
const testPayClient = new Client.WebStoreClient(config);
testPayClient.getCheckoutSession(checkoutSessionId, headers).then((apiResponse) => {
const response = apiResponse;
});
Working with Apache Airflow REST API, and having issues with CORS.
When calling the endpoint using the fetch API in JavaScript I get the following error:
Access to fetch at 'my_url/api/v1/dags/example_bash_operator/tasks' from origin 'my_url' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
This is how I am calling it:
let url = "my_url/api/v1/dags/example_bash_operator/tasks";
let username = 'my_username';
let password = 'my_password';
let headers = new Headers();
headers.set('Authorization', 'Basic ' + btoa(username + ":" + password));
fetch(url, {
headers: headers,
method: 'GET',
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
I also tried adding mode: 'no-cors' but just get the "unexpected end of input" error.
For some background, the following works fine:
starting the airflow webserver and scheduler
accessing the airflow UI
accessing the SwaggerUI authenticating Swagger and calling the REST endpoints with this tool
calling my_url in the address bar of a new browser tab (returns the expected JSON)
I have set the auth_backend in airflow.cfg:
auth_backend = airflow.api.auth.backend.default
Although with the latest REST API version I don't think this makes a difference since everything is set to deny.
I have also set the access control headers in airflow.cfg as described in the docs:
access_control_allow_headers = origin, content-type, accept
access_control_allow_methods = POST, GET, OPTIONS, DELETE
access_control_allow_origin = my_url
...and also tried with wildcard for the access_control_allow_origin:
access_control_allow_origin = *
So the REST calls work fine through Swagger and through the browser address bar, but I cannot call it with fetch using JS. Note that the JS is in an index.html file on the same server (and same root directory) as the airflow files.
The described behavior makes sense, since CORS is used by the browser to prevent attacks from scripts of different resources.
You are still able to fetch via Swagger, Postman or other tools, even through the browser via address bar. But if the policy does not allow to fetch from a different origin, then the browser prevents fetching from your script, which is probably served on a different port. Origin contains host and port.
Your main issue, I cannot help with at the moment.
I've faced the issue of not being able to set the origin policy within the Airflow 2.0 server/API through the (docker-compose) environment variable AIRFLOW__API__ACCESS_CONTROL_ALLOW_ORIGIN.
Maybe it's related to your issue, since I can see from the url of your question (containing the v1), that you're are also using Airflow 2.x.
By the way, the message from chrome is CORS error: Preflight Missing Allow Origin Header, referring to the question in the comments of the original question.
I want to make some API requests to the shipping carriers at the BigCommerce product page and I have some credential for that requests which I don't want to show in my JS code. According to the specific environment of BigCommerce I can't make any changes in back end code. I read a lot of similar questions and now have only one question.
Is it only one way to do that using my own API back end web-server which will store credential information and send POST request to the third party API? Then I will receive that information using a POST request via JS to my own API.
I have tried to run Ruby API application on the nginx web-server. However, it was unsuccessful because browser blocked my fetch() request according to the CORS Policy. I tried to add Access-Control-Allow-Origin: * parameter to the server response header writing it in ruby config file but browser didn't recognize it. Also I tried to set up configuration file on the nginx side but that didn't help me with CORS policy response. That's interesting because using Restlet Application I received response from my own API application with correct information and status "ok".
(async function application() {
let dataRuby = {
url: 'http://IP_address/index',
body: {"name": "21312", "year": "2019"}
};
function getApi(data) {
let myInit = {};
myInit.method = "POST";
myInit.body = JSON.stringify(data.body);
myInit.headers = {
'Content-Type': 'application/json'
};
let myRequest = new Request(data.url, myInit);
return fetch(myRequest).then(
res => res.json()
);
}
let response = await getApi(dataRuby);
console.log(response);
})()
Access to fetch at http://IP_address/index from origin 'null' 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.
import request from 'superagent';
const self = this;
request
.post('https://github.com/login/oauth/access_token')
.set('Content-Type', 'multipart/form-data')
.query({
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
callback: 'http://127.0.0.1:3000/callback',
code,
state,
})
.end((err, res) => {
const token = res.body.access_token;
console.log(token);
self.setToken(token);
});
The code above will give me an error like this
XMLHttpRequest cannot load
https://github.com/login/oauth/access_token?client_id=112asdecf3805fdada12&…127.0.0.1%3A3000%2Fcallback&code=434ebd7bb98d9809bf6e&state=HelloWorld1234.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://127.0.0.1:3000' is therefore not allowed
access.
I have no idea why even though I've registered the oauth application with github and callback url is http://127.0.0.1:3000/callback
While all the actual GitHub API endpoints support CORS by sending the right response headers, it is a known issue that the https://github.com/login/oauth/access_token endpoint for creating an OAuth access token does not support CORS requests from Web applications.
The very specific workaround for this case is to use https://github.com/prose/gatekeeper:
Gatekeeper: Enables client-side applications to dance OAuth with GitHub.
Because of some security-related limitations, Github prevents you from implementing the OAuth Web Application Flow on a client-side only application.
This is a real bummer. So we built Gatekeeper, which is the missing piece you need in order to make it work.
The general workaround is: Use an open reverse proxy like https://cors-anywhere.herokuapp.com/
var req = new XMLHttpRequest();
req.open('POST',
'https://cors-anywhere.herokuapp.com/https://github.com/login/oauth/access_token',
true);
req.setRequestHeader('Accept', 'application/json');
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send('code=' + encodeURIComponent(location.query.code) +
'&client_id=foo' +
'&client_secret=bar');
...
See also How to use Cors anywhere to reverse proxy and add CORS headers.
This is what i'm trying to do:
function fetch() {
$http.get("http://www.myapifilms.com/imdb/top")
.success(function(response) {
console.log(response);
$scope.details = response;
});
};
The error i'm receiving is the following:
XMLHttpRequest cannot load http://www.myapifilms.com/imdb/top. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
I've looked up quite a bit on this issue or CORS but still can't seem to realize what i have to add and in which file(s).
This means that http://www.myapifilms.com does not allow "localhost" origin to access its data.
I could recommend two solutions:
try using http-server by running npm install -g http-server
download a chrome plugin(not recommended) but can be handy for testing https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?utm_source=chrome-app-launcher-info-dialog
use this plugin:
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en
//make headers for service
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('appCurrentVersionNumber', AppConstant.APP_VERSION);
headers.append('WebServiceIdentifier', AppStorage.getItem('webserviceidentifier'));
this.headers = {headers}; this.http.post(API_URL + 'checkInVan', JSON.stringify(userData), this.headers).map(res => res.json());
For this request to succeed, the response from myapifilms.com would need the correct headers set. What you should do is route your request through a server of your own. However you could get around it for testing purposes with a browser extension
Explained in detail here.