JSONP Unexpected Syntax Error (API doesn't support JSONP) - angularjs

My function:
function getMarketData_() {
$http({
method: 'JSONP',
url: 'https://api.coinmarketcap.com/v2/ticker/',
}).then(function(response) {
console.log('ran');
}).catch(function(response) {
console.log('Error');
});
}
The Error:
Uncaught SyntaxError: Unexpected token :
The location of the error in the returned JSON:

The API doesn't support JSONP.
To test click: https://api.coinmarketcap.com/v2/ticker/?callback=test
An API that supports JSONP would send back something like:
test({
"data": {
"1": {
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
"website_slug": "bitcoin",
"rank": 1,
"circulating_supply": 17095362.0,
"total_supply": 17095362.0,
"max_supply": 21000000.0,
"quotes": {
"USD": {
"price": 6530.3,
"volume_24h": 4015800000.0,
"market_cap": 111637842469.0,
"percent_change_1h": -0.66,
"percent_change_24h": -2.31,
"percent_change_7d": -14.6
}
},
"last_updated": 1529097276
}
}
})
For more information, see Wikipedia - JSONP
See also Angular 1.6.3 is not allowing a JSONP request that was allowed in 1.5.8
The API supports CORS.
To test use:
https://www.test-cors.org/#?client_method=GET&client_credentials=false&server_url=https%3A%2F%2Fapi.coinmarketcap.com%2Fv2%2Fticker%2F&server_enable=true&server_status=200&server_credentials=false&server_tabs=remote
This question typically arises when a user attempts to use $http.get and gets:
XMLHttpRequest cannot load https://www.[website].com/ No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4300' is therefore not allowed access.
Then someone suggests $http.jsonp as the workaround. This only works if the API supports JSONP.
For more information, see
XMLHttpRequest cannot load https://www.[website].com/
Why does my JavaScript get a “No 'Access-Control-Allow-Origin' header is present on the requested resource” error when Postman does not?
How to enable CORS in AngularJs
How to use Cors anywhere to reverse proxy and add CORS headers

Related

POST request to Azure Functions App to be send twice before success in React (Axios, Fetch)

I have a simple upload form which onsbubmit should post data to API. In my previous question I struggled to get it running in general, but now CORS went into play. After spending hours on configuring CORS back an forth on Azure Function I got stuck. Finally I managed to verify the server with Curl (Allow Access Origin is matching). This made me thinking there is a bug/feature in how axios handles the requests. So I used fetch just before axios. When deployed one POST fire was successful. I thought I found the problem - so I commented out the axios part. Deployed again. Nothing. So I am back with the working solution but really dirty - one of the methods is firing Error. The other is working. I think the working one is the second one. Any ideas what is happening here?
Here is my code snippet:
formHandler() {
const { formFields } = this.state;
console.log(formFields);
const response = fetch('https://example.com', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formFields),
})
axios({
url: 'https://example.com',
method: 'post',
headers: { 'Content-Type': 'application/json'},
data: formFields
}).then(function(response){
console.log(response);
//Perform action based on response
})
.catch(function(error){
alert(error);
console.log(error.status);
//Perform action based on error
});
}
}
and this is the function.json content on Azure:
{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "direction": "in", "name": "req" }, { "type": "http", "direction": "out", "name": "res" } ] }
I have enabled the methods in the platform features of Azure Function. Should this automatically propagate to function.json? Or should I add this manually?
Axios sends an OPTIONS request prior to sending the POST. It's likely that the Azure Function is denying the OPTIONS request, which prevents the POST request from being successful. Read more about the OPTIONS verb here and here. However, it looks like your function.json is missing a methods key that should have a value of [ "options", "get", "post" ]. This will explicitly allow both OPTIONS and POST (as well as GET).
Your Azure Function's function.json should be something like this:
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"options",
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
For all those who struggle with similar issue the workaround is relatively simple. Stick to content-type application/x-www-form-urlencoded and avoid custom headers, this way it will not force preflight with OPTIONS.
There seems to be a bug either in Axios package and/or Azure Functions on handling posting/responding to OPTIONS call. Check out: https://medium.com/#praveen.beatle/avoiding-pre-flight-options-calls-on-cors-requests-baba9692c21a
for some other related hints.
In firefox I noticed that Option call from Localhost has Origin: null. This maybe AXIOS bug and Azure Function does not accept this call as proper Options call. But I stopped further investigation on his.

How to fix No 'Access-Control-Allow-Origin' header on angular 1 + ajax + CORS policy? [duplicate]

This question already has answers here:
How to enable CORS in AngularJs
(10 answers)
Closed 3 years ago.
I do not know how to fix this problem on my code.
My code is below:
$http({
method: 'POST',
url: "http://urlexample.com.br",
headers : {
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8;",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers" : "X-Custom-Header",
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Methods": "POST",
"Accept" : "application/x-www-form-urlencoded;charset=utf-8;"
},
data: {
"username": login,
"password": senha
}
}).then(function (success) {
callback(success);
}, function (error) {
errorCallback(error);
});
and the errors is this:
"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."
Thanks.
Your are getting this error because you are calling the API which is located in a different domain, and this is what CORS (Cross Origin Resource Sharing) policy prevents unless you allow accessing your API from another domaines.
You can solve this error by installing a package in your backend (laravel-cors if you are working with laravel) it depends on the technology you are using.
have a look at this issues, they will help you understanding and fixing the problem
AngularJS performs an OPTIONS HTTP request for a cross-origin resource
CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true

CORS error when calling post api directly from client

I have a post function that I have tested and is working perfectly. When I call it from my front end, I get the following error:
Access to XMLHttpRequest at 'https://sdigg5u4xb.execute-api.eu-west-1.amazonaws.com/prod/sites' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I have tried disabling CORS and using different cognito identity pools to allow different permissions, but I still get the same error. When testing it in AWS, it is successful with no errors.
Here is where I am calling the API:
import { API } from "aws-amplify";
export default (async function submitSite(values) {
console.log(values);
return API.post("sites", "/sites", {
body: values
})
});
Here is where I am defining the function in my serverless.yml file:
createSite:
handler: CreateSite.main
events:
- http:
path: sites
method: post
cors: true
authorizer: aws_iam
I'd recommend you to check these.
Make sure you enable CORS in your API gateway as described here
Make sure your server less app have CORS enabled here.
Don't forget adding Access-Control-Allow-Origin response header to your function.
module.exports.hello = function(event, context, callback) {
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*", // Required for CORS support to work
"Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
},
body: JSON.stringify({ "message": "Hello World!" })
};
callback(null, response);

Angular resource not returning error response

I'm having this trouble of handling error responses in AngularJS while using $resource. My setup works perfectly with status 200 responses, but when the API throws out a 400 error I just get an empty object.
This is my controller:
$scope.createProduct = function() {
Api.product.save($scope.product).$promise.then(
function(res) {
console.log(res);
},
function(error) {
console.log(error);
}
)
}
This is my Api service:
function ApiService($resource, API_URL) {
return {
product: $resource(
API_URL + '/product/:product_id', { 'product_id': '#product_id' },
{
show: { method: 'GET' },
update: { method: 'PUT', headers: {'Content-Type': 'application/json'} },
}
),
}
}
This is what console.log(error) prints out after a 400 error:
Object {data: null, status: -1, config: Object, statusText: ""}
And finally this is the error response API spits out which I don't get:
{
"errors": {
"message": [
"The town field is required.",
"The postcode field is required.",
]
}
}
Any help would be appreciated, thanks!
EDIT: As an example try sending a POST request to https://api.twitter.com/1.1/statuses/destroy/1.json. If I do this on Postman, I get this error message:
{
"errors": [
{
"code": 215,
"message": "Bad Authentication data."
}
]
}
How do I get this response and the string "Bad Authentication data." in Angular? For some reason I can not do this with my current setup.
The issue may relate to interactions between your API server and CORS.
I am running a Flask based API backend that was presenting this same issue. Troubleshooting led me to discovering that my API was performing a TCP RST when receiving the POST request in around 9 out of 10 connections.
Wireshark capture
The Flask server was logging that the response was being sent back correctly.
2018-08-19 13:26:59,104 INFO: 127.0.0.1 - - [19/Aug/2018 13:26:59] "POST /users/test HTTP/1.1" 419]
Cause
The the cause of the issue was rejecting the POST request in the API backend without reading the POST data first. I refactored my API to always read POST data and this solved the problem.
It's not clear to me how CORS effects this situation, however this problem was only seen when making calls through Angular instead of directly to the API.
The following StackOverflow question pointed me in the right direction to solve this.
No response with POST request and Content-Type "application/json" in flask

Ionic cors issues

I am trying to do authentication in ionic with laravel in the backend. When I was testing it with postman authentication works, and I am getting back a token, but I have cors issues when I am trying to do authentication form ionic, when I do ionic serve. I have tried to set it up as suggested here.
This is my ionic.project file:
{
"name": "myApp",
"app_id": "",
"gulpStartupTasks": [
"sass",
"watch"
],
"watchPatterns": [
"www/**/*",
"!www/lib/**/*"
],
"proxies": [
{
"path": "/api/*",
"proxyUrl": "http://myBackend.app/api"
}
]
}
My gulpfile:
var replace = require('replace');
var replaceFiles = ['./www/js/app.js'];
gulp.task('add-proxy', function() {
return replace({
regex: "http://myBackend.app/api",
replacement: "http://localhost:8100/api",
paths: replaceFiles,
recursive: false,
silent: false,
});
});
gulp.task('remove-proxy', function() {
return replace({
regex: "http://localhost:8100/api",
replacement: "http://myBackend.app/api",
paths: replaceFiles,
recursive: false,
silent: false,
});
});
So when I try to authenticate user, on a failed attempt I get a return from my backend:
POST http://myBackend.app/api/authenticate 401 (Unauthorized)
And when I send the right credentials I get:
XMLHttpRequest cannot load http://localhost:8000/api/authenticate.
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8100' is therefore not allowed
access. The response had HTTP status code 500.

Resources