gpt4 book ai didi

javascript - Node.js 服务器 : Image Upload/Corruption Issues

转载 作者:太空宇宙 更新时间:2023-11-04 02:31:20 26 4
gpt4 key购买 nike

所以我尝试在 Node.js 中编写一个基本文件服务器,并且我尝试上传和存储在其上的所有图像都已损坏。这个问题似乎与 Node 缓冲区处理转换为 UTF-8 并再次转换回来的方式有关(我必须这样做,以便将 POST 正文 header 从二进制数据中取出并远离)。

这是一个简单的 Node 服务器,它展示了我当前的方法以及我遇到的问题:

var http = require('http');

var server = http.createServer(function(request, response) {
if (request.method === "GET") {
// on GET request, output a simple web page with a file upload form
var mypage = '<!doctype html><html><head><meta charset="utf-8">' +
'<title>Submit POST Form</title></head>\r\n<body>' +
'<form action="http://127.0.0.1:8008" method="POST" ' +
'enctype="multipart/form-data"> <input name="upload" ' +
'type="file"><p><button type="submit">Submit</button>' +
'</p></form></body></html>\r\n';
response.writeHead(200, {
"Content-Type": "text/html",
"Content-Length": mypage.length
});
response.end(mypage);

} else if (request.method === "POST") {
// if we have a return post request, let's capture it
var upload = new Buffer([]);

// get the data
request.on('data', function(chunk) {
// copy post data
upload = Buffer.concat([upload, chunk]);
});

// when we have all the data
request.on('end', function() {
// convert to UTF8 so we can pull out the post headers
var str = upload.toString('utf8');
// get post headers with a regular expression
var re = /(\S+)\r\nContent-Disposition:\s*form-data;\s*name="\w+";\s*filename="[^"]*"\r\nContent-Type: (\S+)\r\n\r\n/i,
reMatch = str.match(re);
var lengthOfHeaders = reMatch[0].length,
boundary = reMatch[1],
mimeType = reMatch[2];
// slice headers off top of post body
str = str.slice(lengthOfHeaders);
// remove the end boundary
str = str.replace("\r\n" + boundary + "--\r\n", '');
// convert back to buffer
var rawdata = new Buffer(str, 'utf8');
// echo back to client
response.writeHead(200, {
"Content-Type": mimeType
});
response.end(rawdata);
});
}
});

server.listen(8008);
console.log("server running on port 8008");

要测试它,请在 Node 中运行脚本并在浏览器中转到 127.0.0.1:8008。尝试上传图像并提交表单。每次返回的图像都已损坏 - 即使脚本应该直接将图像数据回显回浏览器。

那么有人知道我在这里做错了什么吗?有没有更好的方法来处理 Node 中的 POST 正文 header ,我还没有想到? (在任何人说任何话之前,不,我不想使用 Express。我想弄清楚并理解这个问题。)

最佳答案

The problem seems to have something to do with the way that Node Buffers handle being converted to UTF-8 and back again

我想你是对的,转换为 UTF-8 是一个坏主意,但可以这样做只是为了处理文件并获取 header 和边界位置,但保持缓冲区文件不变,当你拥有从文件中获取 header 和边界的所有位置时,只需将缓冲区复制到这样的新缓冲区

originalBuffer.copy(newBuffer,0,positionHeader,positionEndBoundary)

var http = require('http');
var fs = require('fs');
var connections = 0;

var server = http.createServer(function (req, res) {
connections++;
console.log(req.url,"connections: "+connections);
if(req.url == '/'){
res.writeHead(200, { 'content-type': 'text/html' });
res.end(
'<form action="/upload" enctype="multipart/form-data" method="post">' +
'<input type="file" name="upload" multiple="multiple"><br>' +
'<input type="submit" value="Upload">' +
'</form>'
);
}

var body = new Buffer([]);
if (req.url == '/upload') {
req.on('data', function (foo) {

//f.write(foo);
body = Buffer.concat([body,foo]);
if(isImage(body.toString())){
console.log("é imagem do tipo "+isImage(body.toString()));
}
else{
console.log("Não é imagem");
res.end("Não é imagem");
}
console.log(body.length, body.toString().length);
});
req.on('end', function () {
// console.log(req.headers);
//I converted the buffer to "utf 8" but i kept the original buffer
var str = body.toString();
console.log(str.length);
imageType = isImage(body.toString());
//get the index of the last header character
//I'm just using the string to find the postions to cut the headers and boundaries
var index = str.indexOf(imageType)+(imageType+"\r\n\r\n").length;
// var headers= str.slice(0,index).split(';');
// console.log(headers);

//Here comes the trick
/*
*I have to cut the last boundaries, so i use the lastIndexOf to cut the second boundary
* And maybe that is the corruption issues, because, I'm not sure, but I guess
* the UTF-8 format only use 7bits to represent all characters, and the buffer can use 8bits, or two hex,
*So, i need to take the difference here (body.length-str.length)
*/
var indexBoundayToBuffer = str.lastIndexOf('------WebKitFormBoundary')+(body.length-str.length);
console.log(index, indexBoundayToBuffer);
//maybe you can change this to use less memory, whatever
var newBuffer = Buffer.alloc(body.length);
/*
*And now use the index, and the indexBoudayToBuffer and you will have only the binary
*/
body.copy(newBuffer,0,index,indexBoundayToBuffer);

// f.end();
//file type
var type = imageType.substr("image/".length);
console.log("END");
fs.writeFile("nameFile."+type,newBuffer,function(err,ok){
if(err){
console.log(err);
return false;
}
res.end();

});
});
}

});

function isImage(str){

if(str.indexOf('image/png')!=-1) return 'image/png';
else if(str.indexOf('image/jpeg')!=-1) return 'image/jpeg';
else if(str.indexOf('image/bmp'!=-1)) return 'image/bmp';
else if(str.indexOf('image/gif'!=-1)) return 'image/gif';
else false;
}

var port = process.env.PORT || 8080;
server.listen(port, function () {
console.log('Recording connections on port %s', port);
});

关于javascript - Node.js 服务器 : Image Upload/Corruption Issues,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26456346/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com