Node.js - JavaScript - HTML - XMLHttpRequest cannot load - javascript

Node.js - Javascript - HTML - XMLHttpRequest cannot load
Basically i have 2 scripts posted below one node.js and 1 javascript/html
i am posting data to my node.js file but i recieve this error and cannot see the result of the nodes.js on my html page.
XMLHttpRequest cannot load http://192.168.2.109:8111/?name=nknk. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://192.168.2.109:8111' is therefore not allowed access
Here is my Node.js file:
var url = require('url');
var http = require('http');
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
if (queryData.name) {
var basevalue = queryData.name;
var value = basevalue.split (":");
var exec = require('child_process').exec;
console.log(value[0]);
console.log(value[1]);
exec ("casperjs test.js " + value[0] + " " + value[1] + '\n',function(err, stdout, stderr) {
response.end(stdout);
});
} else {
response.end("Contact Admin - Not Working\n");
}
});
server.listen(1234);
here is my html/javascript:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<html><head><title>Welcome To ....</title>
<script type="text/javascript">
function textareaToArray(t){
return t.value.split(/[\n\r]+/);
}
function showArray(msg){
for(i = 0; i < msg.length; i++) {
// something per item
var data = {}; //your own data
$.post("http://192.168.2.109:8111" + "?" + $.param({name: msg[i]}), data);
}
// the old code
document.getElementById("message").innerHTML = msg.join("
");
}
</script>
</head>
<body>
<h1> WELCOME TO .... </h1>
<form>
<textarea rows="10" cols="60" name="alpha"></textarea>
<br>
<input type="button" value="show array" onclick="showArray(textareaToArray(this.form.alpha ))">
</form>
<br>
<textarea id="message" rows="6" cols="60" name="message"></textarea>
</body></html>
Can someone help me fix this so that i can get the result back to my html without this error
----edit
this is code i am trying i can still not see the response data from the node.js server
i need to see the response from the exec command that my node server runs i know this takes about 40 seconds to complete but i still do not see anything outputted to html
node.js
var url = require('url')
var http = require('http')
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
if (queryData.name) {
// user told us their name in the GET request, ex: http://host:8000/?name=Tom
var basevalue = queryData.name;
var value = basevalue.split (":");
console.log(value[0]);
console.log(value[1]);
var exec = require('child_process').exec;
exec ("casperjs test.js " + value[0] + " " + value[1] + '\n',function(err, stdout, stderr) {
response.end('_stdout(\'{"content": "blablabla"}\')');
});
} else {
response.end("Contact Admin - Not Working\n");
}
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8999);
~
javascript html
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<html><head><title>Welcome To ....</title>
<script type="text/javascript">
function textareaToArray(t){
return t.value.split(/[\n\r]+/);
}
function showArray(msg){
for(i = 0; i < msg.length; i++) {
// something per item
// var data = {}; //your own data
//$.post("http://192.168.2.109:8121" + "?" + $.param({name: msg[i]}), data);
$.ajax({
url: 'http://192.168.2.109:8999' + '?' + $.param({name: msg[i]}),
dataType: "jsonp",
jsonpCallback: "_stdout",
cache: false,
timeout: 5000,
success: function(data) {
function doSomethingWithData(data) { $('#message').val(data.content); }
},
error: function(jqXHR, textStatus, errorThrown) {
handleError(data);
}
});
}
// the old code
document.getElementById("message").innerHTML = msg.join("
");
}
</script>
</head>
<body>
<h1> WELCOME TO .... </h1>
<form>
<textarea rows="10" cols="60" name="alpha"></textarea>
<br>
<input type="button" value="show array" onclick="showArray(textareaToArray(this.form.alpha ))">
</form>
<br>
<textarea id="message" rows="6" cols="60" name="message"></textarea>
</body></html>

Apparently, your web application is not hosted on the same host as your nodejs server, thus, you are violating the same origin policy.
You can use JSONP:
var http = require('http');
http.createServer(function (req, res) {
console.log('request received');
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('_stdout(\'{"content": "blablabla"}\')');
}).listen(1234);
And your call:
$.ajax({
url: 'http://192.168.2.109:8111' + '?' + $.param({name: msg[i]}),
dataType: "jsonp",
jsonpCallback: "_stdout",
cache: false,
timeout: 5000,
success: function(data) {
doSomethingWithData(data);
},
error: function(jqXHR, textStatus, errorThrown) {
handleError(data);
}
});

This is Same Origin Policy (http://en.wikipedia.org/wiki/Same-origin_policy). Modify your response at the following way:
response.writeHead(200, {
"Content-Type": "text/plain",
"Access-Control-Allow-Origin":"*"
});

My solution is simple.Just require cors module inside the server script side.
Due to CORS(Cross Origin Resource Sharing),which is disabled unless enabled otherwise in most of the modern browser.
In node require cors module in the application and use it accordingly.
Ex:
var cors=require(‘cors’);
var app=express();
app.use(cors());

Related

How does one send a string which is a value from an <input> HTML tag to a NodeJS server?

I understand I could do that with <form action=/serverfile.js method='post'>, but:
(1) How does one do it with Ajax/Fetch API since they need you to send through a file, like a txt file? I'm only trying to send a string.
(2) How would one do it with <form action=/serverfile.js method='post'> too, what would need to be set up on the server end to collect the incoming data?
The answers I have seen use expressjs. I don't want to use expressjs. Is it impossible to do this with vanilla NodeJS?
One way I found to do this with vanilla NodeJS is like so:
HTML
<form action="/nodedemo_trial" method="post">
<label> Username </label> <br/> <br/>
<input type="text" style="width:200px; font-size:1.5rem" id="username"> <br/> <br/>
<label> Password </label> <br/> <br/>
<input type="text" style="width:200px; font-size:1.5rem" id="password"> <br/> <br/>
<input type="submit" value="Log In" style="width:120px; font-size:1.5rem;" > <br/> <br/>
<input type="submit" value="Sign Up" style="width:120px; font-size:1.5rem;" > <br/> <br/>
</form>
NodeJS:
var http = require('http');
var form = require('fs').readFileSync('homepage.html');
http.createServer(function (request, response) {
if (request.method === "GET") {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(form);
}
if (request.method === "POST") {
var postData = '';
request.on('data', function (chunk) {
postData += chunk;
}).on('end', function() {
console.log('User Posted:\n' + postData);
response.end('You Posted:\n' + postData);
});
}
}).listen(1000);
When I do this though, the inputed text doesn't get posted, only "You Posted:". And how would one do that with an HTML page with multiple post requests, if the way to intercept incoming data is request.method === "POST"?
Edit: Used querystring. Still doesn't work.
var http = require('http');
var qs = require('querystring');
var form = require('fs').readFileSync('homepage.html');
http.createServer(function (request, response) {
if (request.method === "GET") {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(form);
}
if (request.method === "POST") {
var postData = '';
request.on('data', function (chunk) {
postData += chunk;
}).on('end', function() {
var post = qs.stringify(postData);
console.log('User Posted:\n' + post);
response.end('You Posted:\n' + post);
});
}
}).listen(1000);
Not async either:
var http = require('http');
var fs = require('fs');
var qs = require('querystring');
http.createServer(function (req, res) {
fs.readFile('homepage.html', function(err, data) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
if (req.method == 'POST') {
var body = '';
req.on('data', function (data) {
body += data;
if (body.length > 1e6)
req.connection.destroy();
}).on('end', function () {
var post = qs.stringify(body);
console.log(post);
//res.end(post);
});
}
return res.end();
});
}).listen(8082);
The top answer here does work.
Apparently, you need to intercept the data with querystring.parse(postData) to convert it into an object. Converting it into a string via either querystring.stringify(postData) or String(postData)/postData.toString doesn't work. Have no
idea why not.

How to display results in a new page after running an ajax function from a node.js express server?

So I'm creating a web app to be a stock management system, I'm using a node.js express server and mysql on the local host. I'm currently trying to when I click on one of the items in the list of stock that it will redirect me to a different html page which would display all the information of the item that is clicked on.
<script>
function item_click(click) {
var data = click.id;
$.get("/getstockitem?id=" + data, function(data) {
window.location.href = "stockInfoPage.html";
});
</script>
This is the ajax function which sends the items id number through to the node server.
const express = require('express');
const app = express();
const path = require('path');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const http = require('http');
// viewed at http://localhost:8080
app.use(express.static('Website'));
app.listen(8080);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.get('/getstockitem', function (req, res) {
var data = req.query;
//var data = 1;
console.log(data);
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password1',
database: 'dissertation_database'
});
connection.connect(function (err) {
if (err) {
return req.next(err);
}
var sql = "SELECT * FROM stock where stock_id=" + data.id;
connection.query(sql, function (err, result) {
console.log(result);
connection.end();
res.json(result);
});
});
});
This is what my node.js server looks like at the moment. The console is logging the id number coming through and the query is pulling through the correct result the only issue is that when it redirects to the stockInfoPage.html it seems that the result is not passed through. I understand that more than likely when I call it in the next page as shown below that it will redo the query, I was wondering whats the best way to be able to get the next page to display the the data?
<script>
$(document).ready(function() {
$.ajax({
type: 'GET',
url: 'http://localhost:8080/getstockitem',
dataType: "json",
success: function(data) {
if (data) {
for (let i = 0; i < data.length; i++) {
console.log(data);
$("#itemName").append($('<p class="itemStaticText">Name: </p><p class="itemInfoText">' + data[i].stock_name + '</p>'));
$("#itemDescription").append($('<p class="itemStaticText">Description: </p><p class="itemInfoText">' + data[i].stock_description + '</p>'));
$("#itemQuantity").append($('<p class="itemStaticText">Quantity: </p><p class="itemInfoText">' + data[i].stock_quantity + '</p>'));
$("#itemShelf").append($('<p class="itemStaticText">Shelf Number: </p><p class="itemInfoText">' + data[i].shelf_number + '</p>'));
$("#itemRack").append($('<p class="itemStaticText">Rack Letter: </p><p class="itemInfoText">' + data[i].rack_letter + '</p>'));
$("#itemPrice").append($('<p class="itemStaticText">Price: </p><p class="itemInfoText">' + data[i].stock_price + '</p>'));
}
}
}
});
});
</script>
Edit
So it is now working with a few minor changes thanks to the suggestion of terrymorse. Below I will put the changes just incase anyone else may have a similar issue.
<script>
function item_click(click) {
var data = click.id;
window.location.href = "stockInfoPage.html?id=" + data;
}
</script>
This time the Id number will be passed through in the url instead and then on the next page I added these lines to pull the id number from the url and now the query works as intended.
(document).ready(function() {
var url = window.location.href;
var id = url.substring(url.lastIndexOf('=') + 1);
$.ajax({
type: 'GET',
url: 'http://localhost:8080/getstockitem?id=' + id,
dataType: "json",
success: function(data) {

Mixed Content Error (Http/Https)

I have mixed content error, on web site used both http and https protocols.
Here's the error from Chrome console:
Mixed Content: The page at 'https://www.amazon.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://www.amazon.com/../?redirect=true'. This request has been blocked; the content must be served over HTTPS.
Here's screenshot with the error: http://prntscr.com/9os5li
Was found some solution like:
Change link from "http://" to "https://" in
Blocked loading mixed active content.
Nothing helped me, because Amazon server drop it all the time when I change link in code or manual from http to https drop it and make it as http.
For example this one Link 2 I can't use here https, because of this I have mixed content error.
Here's my AJAX where I make a call:
$.ajax({
url: "//" + MWS_URL + rest_path,
data: request,
dataType: 'text',
type: 'POST',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
beforeSend: function(req) {
//req.setRequestHeader("User-Agent", "chrome extension");
req.setRequestHeader("x-amazon-user-agent", "chrome extension");
},
success: function(data){
if (onSuccess) {
onSuccess(data);
}
},
error: function(jqXHR, textStatus, errorThrown) {
if (onError) {
onError(jqXHR, textStatus);
}
}
});
setTimeout(callService, 1000);
}
Request:
requests.push(
$.get(link.URL, function (data) {
if (IsCancel()) {
return;
}
var jdata = $($.parseHTML(data));
var parser = new ProductPageParser(jdata, link.URL);
if (!parser.isValidProduct()) {
console.log(link.URL + " is not a valid product, skipped.");
link.processed = true;
return;
}
// Process associated (linked) product on this page according to user preferences.
crawlLinkedProducts(jdata, link.URL, config);
// Store product into a collection.
var product = getProductForParser(parser, link);
//product.dbRawProductURL = urlRaw;
if (product) {
products.push(product);
}
link.processed = true;
})
);
And as I have parse in parser, here's second level parser. I parsed products on main page:
$(productUrls).each(function (index, link) {
if (!link.processed) {
console.log("Download second level -> " + link.URL);
requests_2level.push(
$.post(link.URL, "", function (data) {
if (IsCancel()) {
return;
}
console.log("End download second level -> " + link.URL);
var jdata = $($.parseHTML(data));
var parser = new ProductPageParser(jdata, link.URL);
if (!parser.isValidProduct()) {
console.log(link.URL + " is not a valid product, skipped.");
link.processed = true;
return;
}
var hackUrl = "//amazon.com/o/ASIN/" + parser.getAsin();
link.URL = hackUrl;
var product = getProductForParser(parser, link);
if (product) {
products.push(product);
}
link.processed = true;
})
);
}
});
Anyone have idea how to fix this problem?
If Amazon keep redirecting you from HTTPS to HTTP then there is nothing you can do about that short of:
Complaining hard enough at Amazon that they fix it or
Using a difference service
Decide whether to use http or https and use the same on for every call.

Node JS - call function on server from client javascript

I have written a server.js. Below is the code:-
var http = require('http');
var fs = require('fs');
var my_code = require('./my_code');
function send404Response (response) {
response.writeHead(404, {"Context-Type" : "text\plain"});
response.write("Error 404: Page not found");
response.end();
}
function onRequest(request, response) {
if (request.method == 'GET' && request.url == '/') {
response.writeHead(200, {"Context-Type" : "text\plain"});
fs.createReadStream ('./index.html').pipe(response);
} else {
send404Response(response);
}
}
http.createServer(onRequest).listen(8888);
console.log("Server is now running");
Another server side js written in node is my_code.js. Below is the code:-
var https = require('https');
module.exports.func = myFunction;
function myFunction(myParam) {
console.log (myParam);
}
myFunction(myParam) should be called from client side javascript which will pass myParam. But client side javascript is throwing error saying myFunction is not found.
Please find HTML which contains client side javascript below:-
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#button').click(function() {
$.ajax('/', function(list) {
myFunction($('#myField').text()); //How to do it
});
});
});
</script>
</head>
<form>
<div id="contactno">myField:<input type="text" name="myField"> </div>
<div id="button"><input type="button" value="Submit"></div>
</form>
</html>
Before hitting above html page, I am running node server.js
Please let me know best way to call myFunction from client side.
Thanks in Advance.
Obviously, as you've figured out, you cannot call this function on the client as it's not available there. So your client has to call the server, right?
So the client code would have to pass the $('#myField').text() to the server, and server would have to have another endpoint to receive this, call myFunction on this, and return the result.
You can do it in many different ways, here is one simple example.
Expand the server with another endpoint
function onRequest(request, response) {
if (request.method == 'GET' && request.url == '/') {
response.writeHead(200, {"Context-Type" : "text\plain"});
fs.createReadStream ('./index.html').pipe(response);
} else if (request.method === 'POST' && request.url == '/do-work') {
// asuming sync as in your example
let result = my_code.func(request.body);
response.writeHead(200, {"Context-Type" : "application/json"});
response.write(JSON.stringify({
result: result
});
response.end();
} else {
send404Response(response);
}
}
(I'm not touching on some not-so-good practices and codes here to keep my answer focused to your question.)
You would also have to extend your client code.
$('#button').click(function() {
$.ajax('/', function(list) {
$.ajax({
type: 'POST',
url: '/do-work',
data: $('#myField').text()
success: function(result) {
console.log('Response:', result);
}
}
});
});

Node.js javascript and html script not functioning properly

okay so I am trying to make my html/javascript communicate with my nodes.js server.
what I am trying to do is post data to my nodes.js server then echo the result back into my html/javascript.
the communication is working as in node I have console.log for the postdata and I can see it via the running node console .
problem is I need javascript to wait for the node.js function to complete and then echo me the text produced by node back to the html page.
I just cannot get this to work heres my html/javascript
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<html><head><title>Welcome To ....</title>
<script type="text/javascript">
function textareaToArray(t){
return t.value.split(/[\n\r]+/);
}
function showArray(msg){
for(i = 0; i < msg.length; i++) {
// something per item
var data = {}; //your own data
$.post("http://192.168.2.109:8111" + "?" + $.param({name: msg[i]}), data);
}
// the old code
document.getElementById("message").innerHTML = msg.join("
");
}
</script>
</head>
<body>
<h1> WELCOME TO .... </h1>
<form>
<textarea rows="10" cols="60" name="alpha"></textarea>
<br>
<input type="button" value="show array" onclick="showArray(textareaToArray(this.form.alpha ))">
</form>
<br>
<textarea id="message" rows="6" cols="60" name="message"></textarea>
</body></html>
and here is my node script
var url = require('url')
var http = require('http')
var server = http.createServer(function (request, response) {
var queryData = url.parse(request.url, true).query;
response.writeHead(200, {"Content-Type": "text/plain"});
if (queryData.name) {
// user told us their name in the GET request, ex: http://host:8000/?name=Tom
var basevalue = queryData.name;
var value = basevalue.split (":");
console.log(value[0]);
console.log(value[1]);
var exec = require('child_process').exec;
exec ("casperjs test.js " + value[0] + " " + value[1] + '\n',function(err, stdout, stderr) {
response.end(stdout);
});
} else {
response.end("Contact Admin - Not Working\n");
}
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8111);
can someone please show me and help me fix this thanks
IT is simple.
you need to call the alert in callback. so it will be executed when post request completed.
change your few lines as following
$.post("http://192.168.2.109:8111" + "?" + $.param({name: msg[i]}), function(data){
// data contains your response from server. now you can handle it as you want
});

Categories