So I've had a lot of problems with sending arrays to NodeJS using AJAX, when sending it with JSON, the error function always gets called (asking why that is has given me no answer that I could use).
So I was wondering if anyone knows a different approach to this, the one that I have right now is:
$.ajax({
type: 'POST',
url: 'http://localhost:1337/deposit?steamid=' + steamid,
contentType: "application/json; charset=UTF-8",
dataType: 'json',
data: JSON.stringify({arr:items}),
success: function(data) {
console.log("Tradeoffer has been sent");
},
error: function(data) {
alert("Failed to call bot, please inform us about this issue by DM'ing us at https://twitter.com/csgobeararms");
console.log("Failed to call bot, please inform us about this issue by DM'ing us at https://twitter.com/csgobeararms");
}
});
And on the server side:
app.post('/deposit', function(req, res) {
console.log('Deposit request recieved, info:');
console.log('STEAM ID: ' + req.query.steamid);
console.log('ITEMS: ' + req.body.arr);
});
So I was wondering if someone could tell me another way of sending an array.
If you can tell me what's wrong with this code, that would be awesome to of course.
app.js
//nodejs v4.2.6
var express = require('express');
var app = express();
var fs = require('fs');
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
app.get('/test', function(req, res) {
fs.readFile('test.html',function (err, data){
res.writeHead(200, {'Content-Type': 'text/html','Content-Length':data.length});
res.write(data);
res.end();
});
});
app.post('/deposit', function(req, res) {
console.log('Deposit request recieved, info:');
console.log('STEAM ID: ' + req.query.steamid);
//console.log('ITEMS: ' + req.body.arr);
res.send({'finish':'finish'});
});
app.listen(3000, function(){
console.log('http Express server(worker) listening on port 3000');
});
test.html
<html>
<head>
<script src="https://code.jquery.com/jquery-3.2.0.min.js"></script>
</head>
<body>
<script>
var steamid = 1;
$.ajax({
type: 'POST',
url: 'http://localhost:3000/deposit?steamid=' + steamid,
contentType: "application/json; charset=UTF-8",
dataType: 'json',
data: JSON.stringify({arr:[1,2,3,4]}),
success: function(data) {
console.log("Tradeoffer has been sent");
},
error: function(data) {
alert("Failed to call bot, please inform us about this issue by DM'ing us at https://twitter.com/csgobeararms");
console.log("Failed to call bot, please inform us about this issue by DM'ing us at https://twitter.com/csgobeararms");
}
});
</script>
</body>
</html>
I think that you listen to the wrong URL in Node. From AJAX you call url: http://localhost:1337/deposit?steamid=' + steamid,, but you listen to '/deposit' in Node.
You could try using RegExp:
app.post(new RegExp('/deposit?steamid=[a-zA-Z0-9]')
(assuming that `steamid only contains alphanumerical characters).
Since you're not sending a GET request you might as well get rid of the steamid parameter in the URL and call http://localhost:1337/deposit/' + steamid,; you should then listen to app.post(new RegExp('/deposit?steamid=[a-zA-Z0-9]') in Node.
Hope this helps!
Related
I'm getting net::ERR_CONNECTION_REFUSED error when i open related page with javascript file.
I'm using node.js as a server and , i'm writing post requests in a javascript file for my static pages. service_provider.js is my javascript file for i use writing javascript functions for my static pages(html). node.js is my node.js server file.
service_provider.js
function getJourneyAnalize(
_fonkSuccess,
_fonkBefore,
_fonkError,
_deviceId,
_driverId,
_dateStart,
_dateEnd,
_timeStart,
_timeEnd,
_map,
_kmStart,
_kmEnd
) {
var _fromBody = {
device_id: _deviceId,
driver_id: _driverId,
date_start: _dateStart,
date_end: _dateEnd,
time_start: _timeStart,
time_end: _timeEnd,
map: _map,
km_start: _kmStart,
km_end: _kmEnd
};
$.ajax({
type: 'POST',
url: apiUrl + '/ReportFms/JourneyAnalize',
data: JSON.stringify(_fromBody),
dataType: 'json',
cache: false,
contentType: 'application/json; charset=utf-8',
beforeSend: function (xhr, settings) {
_fonkBefore();
xhr.setRequestHeader('Authorization', 'Bearer ' + currentUser.access_token);
},
success: _fonkSuccess,
error: _fonkError
});
}
node.js
const express = require('express');
const app = express();
var path = require('path');
app.use(
function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
}
)
app.use('/node_modules/jquery/dist', express.static(path.join(__dirname, '../node_modules/jquery/dist')))
app.get('/static-pages/journey-analize-report', function (req, res) {
res.sendFile(path.join(__dirname + '/../static-pages/journey-analize-report/index.html'))
})
app.listen(8000, () => {
console.log('server started');
})
Does you static page shows correctly ?
1 - If your static page is in the parent folder, get rid of the first slash
res.sendFile(path.join(__dirname + '../static-pages/journey-analize-report/index.html'))
2 - to serve jquery script in your static file you could define a personnalized path in place of node_module folder
Replace:
app.use('/node_modules/jquery/dist', express.static(path.join(__dirname, '../node_modules/jquery/dist')))
With
app.use('/js', express.static(path.join(__dirname, '../node_modules/jquery/dist')))
and in your html file require jquery with personnalized path
<script src="/js/jquery.min.js"></script>
3 - if the error still exist, comment app.use functions and jquery script in static page. Reload the server to see if its work
Currently I am using
app.get('/prices/all', function (req, res) {
fs.readFile( __dirname + "/" + "data.json", 'utf8', function (err, data) {
res.set({ 'content-type': 'application/json; charset=utf-8' })
res.end( data );
});
})
which all works great however I want to send an error json response if a user attempts to use any other url e.g. /prices on its own. e.g.:
{status:"failed", error:"wrong get attempt"}
this is hosted on a sub-domain so all links for api.sitename.com/# need to be removed but /prices/all
Express JS allows you to define custom error handling for unmapped routes. As such, you could create a function which would respond with the JSON you specified, when the requested resource is not present 404.
app.use(function(req, res) {
res.send('{"status":"failed", "error":"wrong get attempt"}', 404);
});
http://expressjs.com/en/guide/error-handling.html
For further reading as to why this is the preferred way to handle 404 responses, see below:
http://www.hacksparrow.com/express-js-custom-error-pages-404-and-500.html
Add this as your last route
app.use(function(req, res, next) {
res.status(404).json({status:"failed", error:"wrong get attempt"});
});
Your routes file should look like
app.get('/prices/all', function (req, res) {
fs.readFile( __dirname + "/" + "data.json", 'utf8', function (err, data) {
res.set({ 'content-type': 'application/json; charset=utf-8' })
res.end( data );
});
})
app.use(function(req, res, next) {
res.status(404).json({status:"failed", error:"wrong get attempt"});
});
I'm using express.js as a backend and backbone.js as a front end and MongoDB as a database. I have no problem fetching single posts or collections of posts based on params I pass in, but whenever I try a POST request I get an error. I have tired to call .save() on my model but, I get a cross site domain error.
Here is part of my code
var Post = Backbone.Model.extend({
url: "/posts/new"
});
var Posts = Backbone.Collection.extend({
url: "/categories/all"
});
var PostView = Backbone.View.extend({
model: new Post(),
template: JST["post"],
new_template: JST["new_post"],
el: $(".page"),
events: {
"click .to_category": "updateCurrentCategory",
"submit .new_post": "create"
},
create: function (e){
e.preventDefault();
showLoader();
console.log("subbmited");
this.model.save();
hideLoader();
}
}
You need to include the crossdomain policy in your express.js application header section:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.get('/', function(req, res, next) {
// Handle the get for this route
});
Then if you are using ajax request to submit the post data you have to set crossDomain to true.
If you wish to force a crossDomain request (such as JSONP) on the same
domain, set the value of crossDomain to true. This allows, for
example, server-side redirection to another domain. (version added:
1.5)
http://api.jquery.com/jquery.ajax/
$.ajax({
type: 'POST',
url: 'your/url',
crossDomain: true, // set it to `true`
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
console.log('success');
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
I want to make a Post request using jQuery to mongodb.
running on app localhost:3000.
Using mongoose I can get to display movies using:
router.get('/', function(req, res, next) {
mongoose.model('Movie').find(function(err, titles){
res.render('testdb', { title: 'MYMusic',
className: 'index',
names: titles
});
console.log('names: ', titles);
});
});
But when I want to dynamically post to my database using jQuery using:
$('.save-video-button').on('click', function(event) {
var obj = {
title: 'some title'
};
var URL = 'mongodb://localhost/mydatabase';
$.ajax({
url: URL,
type: "POST",
data: JSON.stringify(obj),
contentType: "application/json",
success: function(data) {
console.log('success --> data :', data);
},
error: function(xhr, text, err) {
console.log('error: ',err);
console.log('text: ', text);
console.log('xhr: ',xhr);
console.log("there is a problem whit your request, please check ajax request");
}
});
});
when I run this ajax request it get an error shown in google chrome dev tools console:
XMLHttpRequest cannot load mongodb://localhost/mydatabase. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
How can I avoid this cross origin request?
Thank you!
ok I got it! for anyone with the same question DO NOT forget to have a router.post in you server side:
router.post('/', function(req, res){
var newmovie = res.body;
console.log(newmovie);
});
so when you make the call you can actually pass the data = res.
this is my set up. However when I send data through the ajax the body is empty. On chrome under network I see the post and the content, with a correct payload:
{"EventName":"asd","PrivacyLevel":1,"TypeInt":1,"ExpectedDate":"asd","Desc":"asd","Down":0,"Up":0,"PostCode":"","Address":"","ID":""}
Most people say its the body parser, I have placed the parsers above the app.use(app.router) I dont know if it creates any conflict with express.json() but when I commented it out it didnt make any difference.
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser('secret'));
app.use(express.session({ secret: 'randomstring' }));
app.use(express.bodyParser());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
$.ajax({
url: window.location.origin + '/registerEvent',
contentType: 'application/json: charset=utf-8',
dataType: 'json',
type: 'POST',
data: JSON.stringify(Event.toJSONString()),
cache: false,
timeout: 5000,
async: false,
success: function (result) {
success = true;
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('error ' + textStatus + " " + errorThrown);
success = false;
}
});
exports.registerEvent = function (req, res) {
if (req.session.lastPage === '/index' && req.xhr) {
console.log(req);
console.log(req.body);
console.log('body: ' + JSON.stringify(req.body));
var test = req.query.EventName;
The data will be available in req.body (the parsed HTTP request body from the AJAX JSON) not req.query (the URL query string).
In your jquery ajax code, use contentType: 'application/json' and that should get it doing the kind of POST request you want.
I think you found a bug in Connect (the middleware that Express uses to parse the body). The code for the bodyParser uses a regular expression to match the "application/json" content type that fails when the "charset=utf-8" is appended to it.
Here is the Connect.js code that I am talking about: https://github.com/senchalabs/connect/blob/master/lib/middleware/json.js#L54
The RegEx that Connect is using is
/^application\/([\w!#\$%&\*`\-\.\^~]*\+)?json$/i
If you run the following code Node you'll see that the one with "charset=utf-8" fails the test:
regex = /^application\/([\w!#\$%&\*`\-\.\^~]*\+)?json$/i
regex.test("application/json") // returns true
regex.test("application/json: charset=utf-8") // returns false
in my case I soveld it by this :
res.header("Access-Control-Allow-Origin", "*");
I copied the code generated by Postman and it worked for me.
Instead of using my normal code
$.ajax({
url: 'http://localhost:3001/api/v1/signup',
data: {
first_name: 'jacob',
last_name: 'ross',
username: 'username',
emailAddress: 'email#email.com',
password: 'somepassword'
},
type: 'POST',
contentType: 'application/json: charset=utf-8', // caused CORS issue
success: function(d){
console.log(d);
}
})
I used this from Postman which worked just fine, and was able to access the params with req.query.
var settings = {
"url": "http://localhost:3001/api/v1/signup?email=email#email.com&password=123456789&first_name=jacob&last_name=ross&username=jacobrossdev",
"method": "POST",
"timeout": 0,
};
$.ajax(settings).done(function (response) {
console.log(response);
});