Node express gets 2 calls from single remote ajax call - node.js

I have a simple ajax call and when I debug on server side (node) I alays get 2 calls...
I thought it was becuase of favicon but I dont think it is because I
app.use(express.favicon('public/assets/favicon.ico'));
I even tried to just do a catch all for favicon so I am pretty sure its the not the issue:
app.post('/_html/favicon.ico', function (req, res) {
console.log('2222');
res.send('{"serverName": 1}');
});
here is the ajax code:
$.ajax({
url: some_url.html,
type: "POST",
crossDomain: true,
data: '{a: 1}',
dataType: "json",
contentType: "application/json",
success: function (res) {
alert(res.serverName);
console.log(res.serverName);
},
error: function (res) {
alert("Bad thing happend! " + res.statusText);
console.log("Bad thing happend! " + res.statusText);
}
});
and for some reason when I debug on node server side, I always get 2 calls from ajax
:(
why?
Thanks,
Sean.

It's preflighted request.
Cause you yse non-standard content type browser first send OPTIONS request and then real POST request with your data.
BTW, {a: 1} is invalid JSON. It must be {"a": 1}.

Related

nodejs get request after post ajax

I have big problem to use AJAX...
I don't want anything after ajax, but GET 304 page after success ajax...
here is my ajax code
$.ajax({
url: "/crawling/list",
type: "POST",
dataType: "json",
cache: false,
// ifModified: true,
async: false,
data: {
'query': input
},
success: (data) => {
...
},
fail: () => {
...
}
})
during about 0.00001 milisecond posted page is loaded and back to original get page..... my nodejs express console like this
my express console...
What's the problem? TT
I find HTML button element issue!
If I don't select button type, page should reload page.
If I use
there is no reload.
Good Good

npm-request doesnt go to fiddler

My POST request doesn't go to Fiddler, even though I specified a proxy url:
router.get('/', function (req, res) {
console.log("in /api/");
request(
{
method: "POST",
uri: "http://api(...)'", //I cut the real url
proxy: "http://127.0.0.1:8888" //
},
function (err, response, body) {
// console.log(response);
res.send(response); // this gives me a real response
});
});
Note: my url: http://node.dev:8080/api is pointing to localhost.
Any idea what I'm doing wrong?
Just realised this was an issue on my side with fiddler. I needed to change the fiddler setting to show all processes, not just web browser.

angular $resource delete won't send body to express.js server

hye,
i am building an app with angular.js and node.js (Express.js) on the server side.
for some reason i am having a problem handling a delete request. no body is getting to the server side.
this is my angular.js resource code:
$scope.deleteProject = function(projectName){
var postData = {username: 'name', projectName: projectName};
Project.deleteProject.delete({}, postData,
function(res){
alert('Project Deleted');
},
function(err){
alert(err.data);
});
}
on the server side i have this:
var deleteProject = function(req, res){
console.log(req.body);
console.log(req.params);
if (req.body.projectName){
//do something
return res.send(200);
}
else
return res.send(400, 'no project name was specified');
}
now for some reason there is no body at all!! it is empty.
i have defined the route as app.delete.
if i change the route in node.js to post and in angular.js to save it works fine.
what am i missing here (banging my head).
thanks.
As per this stack overflow question and the $http service source code, a DELETE request using $http does not allow for data to be sent in the body of the request. The spec for a DELETE request is somewhat vague on whether or not a request body should be allowed, but Angular does not support it.
The only methods that allow for request bodies are POST, PUT, and PATCH. So the problem is not anywhere in your code, its in Angular's $http service.
My suggestion would be to use the generic $http(...) function and pass in the proper method:
$http({
method: 'DELETE',
url: '/some/url',
data: {...},
headers: {'Content-Type': 'application/json;charset=utf-8'}
})
Angular by default sends the Content-Type as text/plain for DELETE requests. Just add this to the headers:
var config = {
method: "DELETE"
url: yourUrl
data: yourData
headers: {"Content-Type": "application/json;charset=utf-8"}
};
$http(config);
If you want to add them to every single DELETE request add this to the app.config method in your main controller:
$httpProvider.defaults.headers.delete = { "Content-Type": "application/json;charset=utf-8" };
If you want to use the $resource object instead of $http you need to add hasBody and headers as follow:
delete: {
method: 'DELETE',
hasBody: true,
headers: {"Content-Type": "application/json;charset=UTF-8"}
}
Worked for me
Just ran into this problem. You'll have to use url params to send an id with delete.
in express:
app.delete('/api/user/:userId', user.remove);
and add to the url in angular:
$http({url: 'whatever/api/'+obj.id, method: 'DELETE'}) ...
The following works for me:
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
$httpProvider.defaults.headers.common['Content-Type'] = 'application/json;charset=utf-8';
XMLHttpRequest is optional but useful if you are sending ajax.
https://docs.angularjs.org/api/ng/provider/$httpProvider for more information.
This worked for me.
$httpProvider.defaults.headers.delete = { "Content-Type": "application/json;charset=utf-8" };
And then
$http.delete(url, { data: data })

The 'Uncaught SyntaxError: Unexpected token : ' in jsonp

I have already get the response json data from server to browser, but it is confused that the data can not be displayed in the browser and I found the error in the console that told me 'Uncaught SyntaxError: Unexpected token :'. Here is my code in node js.
function callFacebook(){
$.ajax({
url: "http://192.168.37.179:8888/facebook/connect?callback_=[TIMESTAMP]",
type: "GET",
dataType: "jsonp",
jsonp:"jsonp",
cache: true,
timeout: 5000,
success: function(data) {
execute(data);
},
error:function() { console.log('Uh Oh!'); }
});
}
and here is the response json data:
res.header('Content-Type','application/json');
res.header('Charset','utf-8');
res.send({"something": "father"});
From the server you are sending just normal JSON data, but on client you are expecting JSONP.
The response from server is not JSONP and browser does throw exception as syntax is wrong.
If you need to send JSONP from server, then if you are using express add extra use:
app.configure(function() {
app.set('jsonp callback', true);
});
Then to send JSONP just slightly change res. You don't need to set any header anymore, as they will be automatically detected:
res.jsonp({ hello: 'world' });
On client side, jQuery will add callback it self, so use just this simplified way:
$.ajax({
url: "http://192.168.37.179:8888/facebook/connect",
type: 'GET',
dataType: 'jsonp',
cache: true,
timeout: 5000,
success: function(data) {
console.log(data)
},
error: function(xhr, status, error) {
console.log('error[' + status + '] jsonp');
}
});
As well if your node is proxied through nginx or any other web platform, don't forget to enable utf8 encoding there.

nodejs - first argument must be a string or Buffer - when using response.write with http.request

I'm simply trying to create a node server that outputs the HTTP status of a given URL.
When I try to flush the response with res.write, I get the error: throw new TypeError('first argument must be a string or Buffer');
But if I replace them with console.log, everything is fine (but I need to write them to the browser not the console).
The code is
var server = http.createServer(function (req, res) {
res.writeHead(200, {"Content-Type": "text/plain"});
request({
uri: 'http://www.google.com',
method: 'GET',
maxRedirects:3
}, function(error, response, body) {
if (!error) {
res.write(response.statusCode);
} else {
//response.end(error);
res.write(error);
}
});
res.end();
});
server.listen(9999);
I believe I should add a callback somewhere but pretty confused and any help is appreciated.
I get this error message and it mentions options.body
I had this originally
request.post({
url: apiServerBaseUrl + '/v1/verify',
body: {
email: req.user.email
}
});
I changed it to this:
request.post({
url: apiServerBaseUrl + '/v1/verify',
body: JSON.stringify({
email: req.user.email
})
});
and it seems to work now without the error message...seems like bug though. I think this is the more official way to do it:
request.post({
url: apiServerBaseUrl + '/v1/verify',
json: true,
body: {
email: req.user.email
}
});
response.statusCode is a number, e.g. response.statusCode === 200, not '200'. As the error message says, write expects a string or Buffer object, so you must convert it.
res.write(response.statusCode.toString());
You are also correct about your callback comment though. res.end(); should be inside the callback, just below your write calls.
Request takes a callback method, its async! So I am assuming, by the time the callback is executed the res.end() might get called. Try closing the request within the callback.
Well, obviously you are trying to send something which is not a string or buffer. :) It works with console, because console accepts anything. Simple example:
var obj = { test : "test" };
console.log( obj ); // works
res.write( obj ); // fails
One way to convert anything to string is to do that:
res.write( "" + obj );
whenever you are trying to send something. The other way is to call .toString() method:
res.write( obj.toString( ) );
Note that it still might not be what you are looking for. You should always pass strings/buffers to .write without such tricks.
As a side note: I assume that request is a asynchronous operation. If that's the case, then res.end(); will be called before any writing, i.e. any writing will fail anyway ( because the connection will be closed at that point ). Move that line into the handler:
request({
uri: 'http://www.google.com',
method: 'GET',
maxRedirects:3
}, function(error, response, body) {
if (!error) {
res.write(response.statusCode);
} else {
//response.end(error);
res.write(error);
}
res.end( );
});
if u want to write a JSON object to the response then change the header content type to application/json
response.writeHead(200, {"Content-Type": "application/json"});
var d = new Date(parseURL.query.iso);
var postData = {
"hour" : d.getHours(),
"minute" : d.getMinutes(),
"second" : d.getSeconds()
}
response.write(postData)
response.end();
And there is another possibility (not in this case) when working with ajax(XMLhttpRequest), while sending information back to the client end you should use res.send(responsetext) instead of res.end(responsetext)
Although the question is solved, sharing knowledge for clarification of the correct meaning of the error.
The error says that the parameter needed to the concerned breaking function is not in the required format i.e. string or Buffer
The solution is to change the parameter to string
breakingFunction(JSON.stringify(offendingParameter), ... other params...);
or buffer
breakingFunction(BSON.serialize(offendingParameter), ... other params...);
The first argument must be one of type string or Buffer. Received type object
at write_
I was getting like the above error while I passing body data to the request module.
I have passed another parameter that is JSON: true and its working.
var option={
url:"https://myfirstwebsite/v1/appdata",
json:true,
body:{name:'xyz',age:30},
headers://my credential
}
rp(option)
.then((res)=>{
res.send({response:res});})
.catch((error)=>{
res.send({response:error});})

Resources