I'm new to node and I'm trying to make a simple xhr to a server and print out to the console when it succeeds with this code:
// Code slice of test.js
xhr.open('GET', uri, true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
console.log("Success!");
} else {
console.log("Waiting...");
}
};
xhr.send();
However, when I run this with node test.js, it only prints out Waiting... once and then never ends execution.
I've tested this code slice in a browser so I know this XHR should work but am I using this wrong?
Related
I'm creating a script which is going to receive a data from API every 24 hours in specific time.
I'm using node-schedule package
After I trying to see the script in terminal or in chrome console log. I receive an error that request is not defined.
I installed RequireJS already, but the error still appears.
I was trying the example from node-schedule documentation itself, also receiving the same error in terminal.
Where is my mistake and how I can fix it?
Code below:
var schedule = require("node-schedule");
var j = schedule.scheduleJob("*/55 20 * * *", function() {
request(
"GET",
"http://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?CMC_PRO_API_KEY=YOUR-API-KEY"
)
.then((r1) => {
var x1 = JSON.parse(r1.target.responseText);
var BTCdata = x1.data.find((d) => d.symbol === "BTC").quote.USD
.volume_24h; // creating a variable to store a BTC request from API
console.log(BTCdata);
})
.catch((err) => {
console.log(err);
});
});
function request(method, url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = resolve;
xhr.onerror = reject;
xhr.send();
});
}
I am currently developping a application in Node-js to launch process throught ssh2. So i use two librairies. Th first one is ssh2 and the second is ssh2-promise. The issue is how I can send an abort signal to my process. I don't understand how I can make this with this two librairies. I can close the socket but the application will continue and I didn't get the PID.
So I try the code below. It launch my process but I can't stop it.
async function sendCommand(commandString) {
let socket = await sshPromise.spawn(commandString);
process.push(socket);
socket.on('data', function (data) {
console.log(data);
});
console.log('Socket push in process array', process);
await sleep(2000);
stopFunctionSocket();
}
function stopFunctionSocket() {
process.forEach( function(socket) {
socket.on('exit', function () {
console.log('Process killed');
});
});
}
sendCommand('sipp/sipp -sn uas 127.0.0.1').then(
result => {
console.log(result);
}
);
I have my output but now, how I can abort the process ?
Thanks a lot.
We can do like this ,
function getWithCancel(url, token) { // the token is for cancellation
var xhr = new XMLHttpRequest;
xhr.open("GET", url);
return new Promise(function(resolve, reject) {
xhr.onload = function() { resolve(xhr.responseText); });
token.cancel = function() { // SPECIFY CANCELLATION
xhr.abort(); // abort request
reject(new Error("Cancelled")); // reject the promise
};
xhr.onerror = reject;
});
};
Which would let you do:
var token = {};
var promise = getWithCancel("/someUrl", token);
// later we want to abort the promise:
token.cancel();
EXPLANATION
You have several alternatives:
Use a third party library like bluebird who can move a lot faster than the spec and thus have cancellation as well as a bunch of other goodies - this is what large companies like WhatsApp do
Pass a cancellation token.
Using a third party library is pretty obvious. As for a token, you can make your method take a function in and then call it, as such:
Try to use this:
socket.kill()
See https://github.com/sanketbajoria/ssh2-promise/blob/bd573d2849a78ebd8315512449f4bd588df3b598/src/sshConnection.ts#L127
I am trying to use XHR to track uploading progress, but at my onprogress callback at event.total I only getting Content-Length from response header instead of uploading file size:
xhr.onprogress = (event) => {
console.log('Progress ' + event.loaded + '/' + event.total);
}
I use Multer to handle file uploading and seems it is not avaible to handle file uploading by default:
https://github.com/expressjs/multer/issues/243
So I tried to handle uploading with progress-stream:
var p = progress({ time: 1 });
request.pipe(p);
p.on('progress', function() {
console.log('Progress...');
});
But it works same way, I only get onle "Progress..." at log and at XHR onprogress event.total I have only Content-Length value instead of file size value. Help please, I have no idea how to fix it!
You don't need get the progress in the backend if you want to show the progress, you only need to know what you've sent from your frontend to backend so you can calculate the upload progress.
In your frontend .js or .html, try something like this:
var formData = new FormData();
var file = document.getElementById('myFile').files[0];
formData.append('myFile', file);
var xhr = new XMLHttpRequest();
// your url upload
xhr.open('post', '/urluploadhere', true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentage = (e.loaded / e.total) * 100;
console.log(percentage + "%");
}
};
xhr.onerror = function(e) {
console.log('Error');
console.log(e);
};
xhr.onload = function() {
console.log(this.statusText);
};
xhr.send(formData);
In the backend you only need a simple endpoint like this:
app.post('/urluploadhere', function(req, res) {
if(req.files.myFile) {
console.log('hey, Im a file and Im here!!');
} else {
console.log('ooppss, may be you are running the IE 6 :(');
}
res.end();
});
Multer is also necessary and remember, xhr only works in modern browsers.
Is there a way to detect if
'Office Editing for Docs, Sheets & Slides'
is installed in Chrome from javascript running in a webpage (not in extension) ?
If it is installed, we want to open and edit the document in a new tab,
while if it is not installed, we want to download the document in CURRENT tab.
I just digged into the source code of this extension, and found it has the following entries in manifest.json
"web_accessible_resources": [ "views/app.html", "views/qowt.html" ]
So you can detect if the extension is installed by querying if views/app.html exists. Just make an ajax call and check the xhr status.
function detectExtension(extensionId, successCallback, failCallback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
successCallback();
} else {
failCallback();
}
}
};
xhr.open("GET", "chrome-extension://" + extensionId + "/views/app.html");
xhr.send();
}
detectExtension("gbkeegbaiigmenfmjfclcdgdpimamgkj", function() {
console.log("The extension is installed");
}, function() {
console.log("The extension is not installed");
});
Fairly new to Node.js
Made an app that runs a server process and serve files (does not use express or any frameworks), Now I'm trying to unit test it.
I'm trying to use a mocha test for that... I intended to start my server process and then run requests against it to test the expected results (stats code, body content and the likes)
However it's not working properly, all the request fail to connect to the server... I'm pretty sure that the issue is because node is juts running one process loop, the server is not running "in the background" while the queries run or possibly the server is not running yet (started ASYNC) while the request are being made ?
Anyway I was wondering what was the proper way to test this, I assume that either I need to have the server run in the background (like a forked process) and/or maybe I need to find a way to wait for the server process to be "up" first but not sure how.
Or at least recommendations on testing such server process (with Mocha or other).
Thanks.
Here is example test code (Updated since original question)
var server = new Server302('./fixture/');
var instance;
describe('Tests', function() {
before(function(done) {
instance = http.createServer(function(request, response) {
console.log(request.url);
server.serve(request, response);
}).listen(8000);
instance.on("listening", function() {
console.log("started");
done();
});
});
after(function(done){
instance.close();
console.log("stopped");
done();
});
it("Should fetch test.html", function(done) {
console.log("test1");
http.get("http://localhost:8000/", function(res) {
res.on('data', function(body) {
console.log(body)
expect(body).toEqual("test");
done();
});
})
});
It seem to Execute in order but still fails with a connection error, whereas it works when testing manually with the browser:
started
test1
․․․stopped
✖ 1 of 1 tests failed:
1) Tests Should fetch test.html:
Error: connect ECONNREFUSED
at errnoException (net.js:670:11)
at Object.afterConnect [as oncomplete] (net.js:661:19)
In your before don't call done until you get the "listening" event fired by the server.
before(function(done) {
instance = http.createServer(function(request, response) {
console.log(request.url);
server.serve(request, response);
}).listen(8000);
instance.on("listening", function() {
console.log("started");
done();
});
});
That should ensure your test connections don't start before the server is ready.
See also the documentation for server.listen
Also had to deal with the body coming in chunks, here is the final thing that works, in case that helps somebody else:
var Server302 = require('../lib/server302.js'),
http = require('http'),
assert = require("assert");
var server = new Server302('./fixture/');
var instance;
describe('Tests', function() {
before(function(done) {
instance = http.createServer(function(request, response) {
server.serve(request, response);
}).listen(8100);
instance.on("listening", function() {
done();
});
});
after(function(done) {
instance.close();
done();
});
it("Should fetch test.html", function(done) {
console.log("test1");
var body = "";
http.get({host: "localhost", port:8100, path: "/"}, function(res) {
res.on('data', function(chunk) {
// Note: it might be chunked, so need to read the whole thing.
body += chunk;
});
res.on('end', function() {
assert.ok(body.toString().indexOf("<a href='/dummy.txt'>") !== -1);
assert.equal(res.statusCode, 200);
done();
});
})
});
it("Should fetch dummy.txt", function(done) {
http.get({host: "localhost", port:8100, path: "/dummy.txt"}, function(res) {
res.on('data', function(body) {
assert.equal(res.statusCode, 200);
assert.ok(body.toString().indexOf("test") === 0);
done();
});
});
});
it("Should get 404", function(done) {
http.get({host: "localhost", port:8100, path: "/qwerty"}, function(res) {
assert.equal(res.statusCode, 404);
done();
});
});
});
Using SuperTest
Here is a full and straightforward example using SuperTest and Mocha:
var server = new Server302('./fixture/');
var request = require('supertest');
describe('Tests', function() {
it('Should fetch test.html', function(done) {
request(server)
.get('/')
.expect('test', done);
});
});
SuperTest allows you to:
Request your server using SuperAgent (much easier to use than the low level http agent).
Bound your server to an ephemeral port so there is no need to keep track of ports (you can still do it manually if needed).
Use sugary expect methods that works with Mocha (or any other test framework).