I need to get zip from rest call (for simulation I use postman with binary option for post and add a little zip file with folder and html file),during the simulation I want to get the data with express and extract the zip and put in some folder under C drive.
Currently when I run the following program(this is all the code which i've tried) but im getting error
events.js:85
throw er; // Unhandled 'error' event
^ Error: incorrect header check
at Zlib._handle.onerror (zlib.js:366:17)
var express = require('express'),
fs = require('fs'),
zlib = require('zlib'),
app = express();
app.post('/', function (req, res) {
var writeStream = fs.createWriteStream('C://myFolder', {flags: 'w'});
req.pipe(zlib.createInflate()).pipe(writeStream);
});
var server = app.listen(3000, function () {
console.log("Running on port" + 3000)
}
)
in postman header i've added the following
content-Type ----> application/zip
How should I overcome this issue and save the zip ? there is other recommended (zlib)library to get extract and save zip?
zlib is meant to extract gzipped or deflated data, not .ZIP files.
You can use the node-unzip module for those:
var unzip = require('unzip');
...
app.post('/', function(req, res) {
var extractor = unzip.Extract({ path : 'C://myFolder' }).on('close', function() {
res.sendStatus(200);
}).on('error', function(err) {
res.sendStatus(500);
});
req.pipe(extractor);
});
If Postman can't handle uploads like this (as suggested in the comments), you can test using cURL:
$ curl -XPOST localhost:3000 --data-binary #test.zip
Related
I created an express server, which also writes some text into a file I have in the project directory and executes a cmd command. Locally, it works, but if I deploy it to App Engine and try to make a request I get error 500.
If there isn't a way to do this, what could I do instead of it? I guess for fs, storing it in Cloud Storage, but I don't know about exec-
The code:
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const { exec } = require('child_process');
var fs = require('fs')
const app = express();
app.use(bodyParser.json());
app.use(cors());
module.exports = app
app.post("/", (req,res) =>{
console.log("Get from /");
console.log(req.body.data)
fs.writeFileSync('../log.txt', req.body.data);
exec('npx hardhat run scripts/deploy.js --network goerli',
(error, stdout, stderr) => {
if (error !== null) {
console.log(`exec error: ${error}`);
}
else{
var addr = fs.readFileSync('../address.txt','utf8')
res.send(addr);
}
})
res.send(req.body.data);
});
// starting the server
app.listen(8080, () => {
console.log('listening on port 8080');
});
For App Engine Standard, you can't write to the local file system. You can write to /tmp which is a temporary directory. All files in this directory are stored in your instance's RAM which means you lose the file when the instance goes down (see documentation)
For App Engine Flexible, you can write to local disk but the disk is re-initialized whenever the VM is (re)started (see documentation)
Best thing would be to write to cloud storage
I'm sending the following JSON string to my server.
(
{
id = 1;
name = foo;
},
{
id = 2;
name = bar;
}
)
On the server I have this.
app.post('/', function(request, response) {
console.log("Got response: " + response.statusCode);
response.on('data', function(chunk) {
queryResponse+=chunk;
console.log('data');
});
response.on('end', function(){
console.log('end');
});
});
When I send the string, it shows that I got a 200 response, but those other two methods never run. Why is that?
I think you're conflating the use of the response object with that of the request.
The response object is for sending the HTTP response back to the calling client, whereas you are wanting to access the body of the request. See this answer which provides some guidance.
If you are using valid JSON and are POSTing it with Content-Type: application/json, then you can use the bodyParser middleware to parse the request body and place the result in request.body of your route.
Update for Express 4.16+
Starting with release 4.16.0, a new express.json() middleware is available.
var express = require('express');
var app = express();
app.use(express.json());
app.post('/', function(request, response){
console.log(request.body); // your JSON
response.send(request.body); // echo the result back
});
app.listen(3000);
Updated for Express 4.0 - 4.15
Body parser was split out into its own npm package after v4, requires a separate install npm install body-parser
var express = require('express')
, bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.post('/', function(request, response){
console.log(request.body); // your JSON
response.send(request.body); // echo the result back
});
app.listen(3000);
For earlier versions of Express (< 4)
var express = require('express')
, app = express.createServer();
app.use(express.bodyParser());
app.post('/', function(request, response){
console.log(request.body); // your JSON
response.send(request.body); // echo the result back
});
app.listen(3000);
Test along the lines of:
$ curl -d '{"MyKey":"My Value"}' -H "Content-Type: application/json" http://127.0.0.1:3000/
{"MyKey":"My Value"}
For Express v4+
install body-parser from the npm.
$ npm install body-parser
https://www.npmjs.org/package/body-parser#installation
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res, next) {
console.log(req.body) // populated!
next()
})
For those getting an empty object in req.body
I had forgotten to set
headers: {"Content-Type": "application/json"}
in the request. Changing it solved the problem.
#Daniel Thompson mentions that he had forgotten to add {"Content-Type": "application/json"} in the request. He was able to change the request, however, changing requests is not always possible (we are working on the server here).
In my case I needed to force content-type: text/plain to be parsed as json.
If you cannot change the content-type of the request, try using the following code:
app.use(express.json({type: '*/*'}));
Instead of using express.json() globally, I prefer to apply it only where needed, for instance in a POST request:
app.post('/mypost', express.json({type: '*/*'}), (req, res) => {
// echo json
res.json(req.body);
});
const express = require('express');
let app = express();
app.use(express.json());
This app.use(express.json) will now let you read the incoming post JSON object
Sometimes you don't need third party libraries to parse JSON from text.
Sometimes all you need it the following JS command, try it first:
const res_data = JSON.parse(body);
A beginner's mistake...i was using app.use(express.json()); in a local module instead of the main file (entry point).
I have an express server.
server.js
const express = require('express');
const app = express();
var json = require("./sample.js")
app.use("/", (req, res)=>{
console.log("----------->", JSON.stringify(json));
res.status(200).send(JSON.stringify(json));
});
app.listen(2222,()=>{
console.log(`Listening on port localhost:2222/ !`);
});
sample.js
var offer = {
"sample" : "Text",
"ting" : "Toing"
}
module.exports = offer ;
Once i execute the server.js file, it fetches the json data from sample.js file. If I update the data of the sample.js while the server.js is still executing I dont get updated data. Is there any way
to do the same, without stopping the execution of server.js.
Yes, there is a way, you have to read the file every time a request occurs (or cache it for a time, for a bit better performance).
The reason why require does not work is that NodeJS automatically caches modules for you. So even if you would require it inside the request handler (in the use), it won't work.
Because you cannot use require, it won't be convenient (or performant) to use a module. So your file should be in JSON format instead:
{
"sample" : "Text",
"ting" : "Toing"
}
To read it, you have to use the fs (file system) module. This allows you to read the file from disk every time:
const fs = require('fs');
app.get("/", (req, res) => {
// To read as a text file, you have to specify the correct
// encoding.
fs.readFile('./sample.json', 'utf8', (err, data) => {
// You should always specify the content type header,
// when you don't use 'res.json' for sending JSON.
res.set('Content-Type', 'application/json');
res.send(data)
})
});
It is important to know, that now data is a string, not an object. You would need JSON.parse() to get an object.
Also use is not recommended in this case. It is for middlewares, you should consider using get (as in my example), or all if you want to handle any verb.
You need to read the file at runtime:
fs = require('fs');
function getJson() {
fs.readFile('sample.json', (err, jsonData) => {
if (err) {
console.log('error reading sample.js ', err)
}
return(jsonData)
}
}
}
make sure your sample.js is instead just a json object.
I try to create a server, which can receive a file from an HTTP request.
I use Postman as user agent and I add a file to the request. This is the request:
POST /getfile HTTP/1.1
Host: localhost:3000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 9476dbcc-988d-c9bd-0f49-b5a3ceb95b85
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="test.xls"
Content-Type: application/vnd.ms-excel
------WebKitFormBoundary7MA4YWxkTrZu0gW--
But when the request reaches the server I can not find the file in it (I mean in the request).
I tried to receive it from the body part of the request, but it returned > {} <. I tried to figure out, how can I refer to the name of the file, but unfortunately I can not find any reference in the request header for the name of the file...
Can anybody help me to find out, what should I do?
As a follow up to my comment, you can use the multer module achieve the thing that you want:
https://www.npmjs.com/package/multer
const express = require('express');
const multer = require('multer');
const app = express();
const upload = multer();
app.post('/profile', upload.array(), function (req, res, next) {
// req.body contains the text fields
});
var app = require('express')();
var multer = require('multer');
var upload = multer();
app.post('/your_path', upload.array(), function (req, res, next) {
// req.files is array of uploaded files
// req.body will contain the text fields, if there were any
});
You need to parse the form data from the request. There are a few packages that solves this problem, notably formidable, busboy (or busboy-connect), parted and flow.
Here's a solution using formidable, it is my preferred solution for things like image uploads because it saves to disk.
If you just want to read the file, you can use one of the other packages above.
Install formidable
npm install formidable --save
Then, in your server, you will have to parse the data from the client:
// Somewhere at the start of your file
var IncomingForm = require('formidable').IncomingForm
// ...
// Then in your request handler
var form = new IncomingForm()
form.uploadDir = 'uploads'
form.parse(request, function(err, fields, files) {
if (err) {
console.log('some error', err)
} else if (!files.file) {
console.log('no file received')
} else {
var file = files.file
console.log('saved file to', file.path)
console.log('original name', file.name)
console.log('type', file.type)
console.log('size', file.size)
}
})
A few things to note:
formidable saves files with new names, you can use fs to rename or move them
you can set form.keepExtensions = true if you want saved files to keep their extensions
how i can send file for that the server read it with fs.createwriteStream();
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res) {
// This opens up the writeable stream to `output`
var writeStream = fs.createWriteStream('./output');
// This pipes the POST data to the file
req.pipe(writeStream);
req.on('end', function () {
res.end('ok upload file');
});
// This is here incase any errors occur
writeStream.on('error', function (err) {
console.log(err);
});
}).listen(8080);
i use this command with console linux:
curl --upload-file hello.txt 127.0.0.1:3000 and work ok but i don't know how send file with url
somebody know?
curl -i -F name=test -F filedata=#localfile.jpg 127.0.0.1:3000