Ajax calls from node to django - ajax

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'

Related

React js AJAX sends sometimes GET instead of POST and getting 304 strange

I've got a problem and I have no idea why it appears. The circumstances of its appearance are very strange for me...
I've got a POST REST service /login. It expects json {"email":email,"password":password}. I am using ajax and everything works correctly... except for the case when email (is in real format) contains '#' sign and some letters before and after( I know it is strange but only in this case such error appears). When I pass email i.e "mum#mum.com" then few things are happening:
I see that browser sends GET request instead of POST and obtains 304 http status
In the browser console I see infomation "The development server has disconnected. Refresh the page if necessary" and page refreshes automatically
The above things happen only when email is in format I described above.When I pass "aaa" or "aaa#" as email everything works correctly(browser sends POST request and I don't get error in console).
I honestly have no idea why this happens... would be extremely grateful for your help and I will answer all your questions concerning this.
PS.
When I use REST web service tool in IntellJ everything always works fine.
handleLogin() {
const input = {
email: this.state.email,
password: this.state.password
};
$.ajax({
url: CONST.USER_SERVICE + "/login",
type: "POST",
data: JSON.stringify(input),
contentType: "jsonp"
})
.fail(function () {
alert("Wrong data");
})
.always(function (arg1, arg2, arg3) {
if (arg3.status === 200) {
alert("ok!");
}
}.bind(this));
}
Try making the ajax request like data: input without stringify. Ajax expects an object.

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.

Cross Domain Ajax call EasyXDM

I'm trying to make a cross domain Ajax call using EasyXDM, because this gives support for IE apparently.
I have the following code, It says in the documentation that you need to call the cors file on the other domain, but it mentions you can skip that part, I want to skip it because I can't upload the cors file there and they have allowed my domain in the headers anyway. How do I write the code without declaring the cors file?
var xhr = new easyXDM.Rpc();
var response;
function getState(){
xhr.request({
url: "http://somedomain.com/misc/promo_getstate.php",
method: "POST",
data: {
email: 'sofia#hotmail.com',
source: '1304_Spring_dly',
country: 'DE',
}
}, function(response){
alert(response.status);
alert(response.data);
});
I know it's a little late, but you might find this link helpful (it's a blog post specifically about using easyxdm to do cross-domain AJAX):
http://easyxdm.net/wp/2010/03/17/cross-domain-ajax/

How to debug the ajax request in django

I know that for example:
def home(request):
if request.method == 'POST':
k = 'p' % 1
return HttpResponse(simplejson.dumps(dict()), mimetype='application/javascript')
else:
k = 'p' % 1
return render_to_response('index.html',locals());
url(r'^$', 'app.home'),
If I use the browser to visit the home page, django will return a debug page to me and show that there is an error in k = 'p' % 1
But if I use the $.ajax() to send a post to this view, the console of chrome only show POST http://(some url here):8000/ 500 (INTERNAL SERVER ERROR)
so is there any good way to debug the second case?
I have no idea about debug the django, is there anybody have better way to debug the django?
thanks
have a look at sentry (and the corresponding raven)
(the Network tab should be able to show you the request and the corresponding response. i believe newer django versions even give you a more bare-bones version of the stacktrace if the request was ajax)
There is an error CallBack in ajax. It will spew out the actual error.
$.ajax({
type: 'POST',
url: '{% url 'url_name_for_your_view_here' %}',
data: {'csrfmiddlewaretoken': '{{csrf_token}}'},
dataType: "text",
success: function(response) {
//do something here if everything goes well
},
error: function(rs, e) {
alert(rs.responseText); //throw actual error, just for debugging purpose
alert('Oops! something went worng..'); // alert user that something goes wrong
}
});
There are a number of third party apps make debugging ajax easier. I've used this in the past with success: https://github.com/yaniv-aknin/django-ajaxerrors
Or if you prefer not use an app, chrome developer tools will likely be enough, as is suggested in this thread: Django: Are there any tools/tricks to use on debugging AJAX response?

Securing (ssl) a nodejs/express web service and calling it cross-domain with $.ajax()

I've set up a nodejs app like this:
var express = require('./../../../Library/node_modules/express');
var https = require('https');
var app = express();
httpsOptions = {
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem') // SELF-SIGNED CERTIFICATE
}
var server = https.createServer(httpsOptions);
app.get('/myservice', function(req, res) {
...
}
server.listen(8443);
I have opened the 8443 port in my server for inbound requests.
From a browser, if I open https://mydomain/myservice:8443 I get the untrusted connection warning from the browser, which seems logical.
Then from a test.html that I run from my local computer (to test the cross-domain issue), I do something like this:
function testService(){
var data = { some JSON };
$.ajax({
url: 'https://myserver:8443/myservice',
dataType: "jsonp",
data: data,
jsonpCallback: "_mycallback",
cache: false,
timeout: 5000,
success: function(data) {
alert(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Error: ' + textStatus + " " + errorThrown);
}
});
}
My problem is that this request times out, and I don't think it even reaches the service.
Any idea why?
Whenever I make this request reach the server, hopefully thanks to your kind responses, what will happen with the browser warning for the untrusted certificate? Will that stop $.ajax() from silently calling the server and receiving the response?
The reason that your clients' JSONP request times out could be practically anything. Because of the way JSONP works, you can only ever know whether the request fails or succeeds, and when it fails it will always be because of a timeout. That said, its pretty much guaranteed to fail if you haven't saved the servers self-signed cert on the client. To do so, make sure that you tell your browser to always trust the servers' certificate. In Firefox you can also go Preferences->Encryption->View Certificates->Your Certificates->Import... to add the certificate to Firefox. Other browsers should have a similar interface.
To solve a potential cross domain issue, try adding the following to your app.get('/myservice'):
res.header("Access-Control-Allow-Origin:", "*");
res.header("Access-Control-Allow-Methods:", "GET");
Additionally, different browsers handle these things differently. In my experience Firefox is sometimes more lenient than Chrome, but I would definitely test in both.
To test the HTTPS issue, first I would try just setting up a regular expressjs server (no encryption) and not using https:// in your request. If the request then succeeds you know that the problem is the SSL. If so, make sure that when your browser gives a security warning you enable any options allowing you to permanently add that site to your trusted hosts.
Also, I believe that this line:
var server = https.createServer(httpsOptions);
should be:
var server = https.createServer(httpsOptions, app);
(From: http://expressjs.com/api.html#app.listen)
You may also want to add the following code below var server = https.createServer(httpsOptions); for debugging (so that you can easily see if your server receives the request):
app.get('*', function(req, res, next) {
// You *should* also be able to add the response headers here, although I haven't tried.
console.log('Request received', req, res);
next();
})
Hopefully that helps!

Resources