Request working in CURL but not in Ajax - ajax

I have a Scrapyd server running and trying to schedule a job.
When i try below using CURL it is working fin e
curl http://XXXXX:6800/schedule.json -d project=stackoverflow -d spider=careers.stackoverflow.com -d setting=DOWNLOAD_DELAY=2 -d arg1=val1
After that i have done a small code UI in angular to have a GUI for this,
I have done a AJAX request to do the above.
var baseurl = GENERAL_CONFIG.WebApi_Base_URL[$scope.server];
var URI = baseurl +"schedule.json"; //http://XXXXX:6800/schedule.json
var headers = {'content-type': 'application/x-www-form-urlencoded'}
console.log(URI)
$http.post( URI,data = $scope.Filters, headers).success(function (data, status) {
console.log(data)
}).error(function (data, status) {
console.log(status);
alert("AJAX failed!");
});
but i am getting No 'Access-Control-Allow-Origin' header is present on the requested resource. error.
Can any one help me how to resolve this ?
And why it is working in CURL but not in my AJAX.
Thanks,

This is because of browser protection called Same-origin policy. It prevents ajax requests across a different combination of scheme, hostname, and port number. Curl has no such protection.
In order to prevent it you will either have to put both the api and client app on the same domain and port or add the CORS header 'Access-Control-Allow-Origin' to the server.
One other option is to use JSONP. This may be suitable in this case to just get json data. It's not suitable for rest apis. In angular use $http.jsonp for this

Related

CORs error when accessing Square V2 API

I'm making a client-side request out to V2 of the Square API using Vue and Axios. My Vue component is as follows:
import axios from 'axios';
export default {
mounted() {
var instance = axios.create({
baseURL: 'https://connect.squareup.com/v2/',
timeout: 1000,
headers: {
'Authorization': 'Bearer xxxxxxxxxxxxxxxxx',
'Accepts': 'application/json',
'Content-Type': 'application/json'
}
});
instance.get('catalog/list')
.then(function (response) {
console.log(response);
}) ;
}
}
However, when I make that call, I receive the following error:
Failed to load https://connect.squareup.com/v2/catalog/list: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://local-env.dev' is therefore not allowed access. The response had HTTP status code 403.
That error suggests that there is some configuration that has to happen on the Square side, but I saw no opportunity to whitelist domains, etc.
Has anyone come across this error before, regardless of service, and if so, how did you resolve?
I don't think the Square API supports being called from a browser. I used Postman to do an OPTIONS request on https://connect.squareup.com/v2/catalog/list and the response was a NOT_FOUND. The OPTIONS request is needed for proper CORS support.
Plus, if you did this, I would think your auth token would need to be sent to the client -- thus exposing it to everyone. It looks like the Square API is only designed to be called from a server. But that is just based on me skimming the docs a bit. I have no experience using their API.
When doing OAuth authorization request you are not supposed to do it from your application. Create and URL with the parameters and open it in a new browser window or tab, Something like:
const grants='MERCHANT_PROFILE_READ CUSTOMERS_READ CUSTOMERS_WRITE PAYMENTS_READ PAYMENTS_WRITE PAYMENTS_WRITE_ADDITIONAL_RECIPIENTS PAYMENTS_WRITE_IN_PERSON';
const params = new HttpParams()
.set('scope', grants)
.set('client_id', <YourSquareApplicationId>)
.set('state', '1878789');
const requestUrl = `${<squareUrl>}/oauth2/authorize?${params.toString()}`;
window.open(requestUrl, "_blank");
That new window is supposed to ask the end user to login to his account and accept or deny the request.

Static webpage in s3 bucket and making ajax request inside the page to call lambda function

I have uploaded a html page in s3 bucket and that html page makes an ajax post request to the api gateway url to send an email.
The problem is that the same api gateway url if I use postman to make a post request to it the email is sent but with the html page in s3 having ajax code doesn't work.
Any idea, or help will be helpful for me. Thanks
----Ajax code
$.ajax("https://apigateway-url/email_sending", {
"type": "POST",
"data": JSON.stringify(formData),
"contentType": "application/json"
}).done(function () {
console.log("Done")
}).fail(function () {
console.log("Failed");
// console.log(data);
});
I have tried so many help from net like edit cors configuration in s3 or enable cors in api gateway, but none worked for me.
NodeJs code for send Email
var sendemail = require('./sendemail')
app.post('/email_sending',function(req,res){
console.log("Request received For sending mail")
sendemail.send(req.body,function(err, data){
// res.setHeader('Access-Control-Allow-Origin', '*');
res.end("Success");
})
})
sendemail module snippet is :
ses.sendemail(data, done)
I considered this website but didn't get the solution : https://codehabitude.com/2016/04/05/forms-to-emails-using-aws-lambda-api-gateway/
Its very likely you aren't setting up the CORS headers correctly in apigateway. The apigateway documentation http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html clearly describes the process.
Once you've setup CORS and deployed the changes, you can verify the CORS preflight request using the below curl command
curl -H "Origin: http://example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: X-Requested-With" \
-X OPTIONS --verbose \
https://apigateway-url/email_sending
Also, note that you need to deploy the changes after you setup CORS (Big blue Deploy API button - http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api-with-console.html) before the change is reflected in your API

Amazon CORS-enabled api returns no 'Access-Control_allow_Origin' header

After setting up Amazon API Gateway CORS as instructed, I still get the following error when send an Ajax POST request.
XMLHttpRequest cannot load https://-------.execute-api.us-west-2.amazonaws.com/--------. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://------.s3-website-us-west-2.amazonaws.com' is therefore not allowed access. The response had HTTP status code 400.
I'm using Amazon S3 to host the website, which does not support web script so I can't use python or php to fix this.
I'd really appreciate any help.
Could it be that you're using Lambda-proxy integration and your Lambda is not returning those headers? If that's the case, you have to add those headers yourself.
This is how I use to create the response that I return using callback(null, response).
function createResponse(statusCode, body) {
const headers = {
'Access-Control-Allow-Origin': '*',
}
return {
headers,
statusCode,
body: body ? JSON.stringify(body) : undefined,
}
}

Ajax calls from node to django

I'm developing a django system and I need to create a chat service that was in real-time. For that I used node.js and socket.io.
In order to get some information from django to node I made some ajax calls that worked very nice when every address was localhost, but now that I have deployed the system to webfaction I started to get some errors.
The djando server is on a url like this: example.com and the node server is on chat.example.com. When I make a ajax get call to django I get this error on the browser:
XMLHttpRequest cannot load http://chat.example.com/socket.io/?EIO=3&transport=polling&t=1419374305014-4. Origin http://example.com is not allowed by Access-Control-Allow-Origin.
Probably I misunderstood some concept but I'm having a hard time figuring out which one.
The snippet where I think the problem is, is this one:
socket.on('id_change', function(eu){
sessionid = data['sessionid']
var options = {
host: 'http://www.example.com',
path: '/get_username/',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': sessionid.length
}
}
var request = http.request(options, function(response) {
response.on('data', function(msg){
console.log('Received something')
if(response.statusCode == 200){
//do something here
}
}
})
})
request.write(sessionid);
request.end();
});
And I managed to serve socket.io.js and make connections to the node server, so this part of the setup is ok.
Thank you very much!
You're bumping into the cross origin resource sharing problem. See this post for more information: How does Access-Control-Allow-Origin header work?
I am NOT a Django coder at all, but from this reference page (https://docs.djangoproject.com/en/1.7/ref/request-response/#setting-header-fields) it looks like you need to do something like this in the appropriate place where you generate responses:
response = HttpResponse()
response['Access-Control-Allow-Origin'] = 'http://chat.example.com'

Using ajax to GET a token from external site returns empty response

I have two sites right now. One that has a token and one that is supposed to allow a user to do stuff with the token.
When I visit the first site that has the token, mySite.local/services/session/token it shows it: OTV4Gu9VQfjIo2ioQ0thajdEJ6nEINoxsLuwgT_6S0w
When I am on the page that is supposed to GET this token, I get an empty response and the error for the ajax function is thrown.
The weird part is that when investigating the issue with firebug, I can see the response for the ajax request is 43B - the same size as the token. So for some reason the page with the token is being hit properly, but the response is not coming through.
Here is a screenshot of the firebug response:
And here is the JQuery with the ajax request:
var nid; //global node id variable
$('html').click(function(){
try {
$.ajax({
url:"http://mySite.local/services/session/token",
type:"get",
dataType:"text",
error:function (jqXHR, textStatus, errorThrown) {
alert('error thrown - ' + errorThrown);
console.log(JSON.stringify(jqXHR));
console.log(JSON.stringify(textStatus));
console.log(JSON.stringify(errorThrown));
},
success: function (token) {
//Do some stuff now that token is received
}
});
}
catch (error) {
alert("page_dashboard - " + error);
}
});
Your running into the Same Origin Policy which essentially states any request done by client side/browser language like Javascript must be on the same port, with the same domain name and the same protocol. In your case http://mysitemobile.local does not equal http://mysite.local so you're request is being blocked. Firebug's way of displaying that is no response with 43 bytes.
There are two ways to work around this, Cross-origin resource sharing (CORS) or JSONP. CORS is a HTTP header that is added to the server you are requesting to and provides a whitelist of acceptable domains that are allowed break the same origin policy. Most recent browsers support this header.
The other option is JSONP, wraps a JSON object into a Javascript function that is called using <script> tags normally. If the other server returns {status: 0} and you have a function called parseStatus() in your code that the remote server would wrap into parseStatus({status:0}); thus calling your function without having to worry about the same origin policy.

Resources