- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
所以我尝试在 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/
void *insert_rear_node(void *arg) { int *argument=(int *)arg; int value=*argument; //Assume
嘿,我的代码在执行后说“帐户”已损坏... 这是什么意思,我该如何解决? #include #include using namespace std; class BankAccount { pr
我正在使用 PHP 创建一个应用程序并涉及 MySQL。如果在请求过程中发生错误,我将如何“将查询分组在一起”,检查它是否会成功,然后对真实表进行实际影响。如果对表的实际更新失败,则恢复到更新之前的状
我正在尝试在 CentOs6 上使用 EasyBuild 编译 tensorflow,但 Bazel 捕获了错误的 binutils 目录,不幸的是,这是一个硬编码目录,以错误的汇编器结尾。 如果我尝
我正在尝试在 OS X Mavericks 上创建一个 AppleScript 库。我已将文件保存到 ~/Library/Script Libraries作为脚本包;它有一个正确的(据我所知;见下文)
我在 Eclipse Indigo 中开发 Android 项目已经有一年了,该 PC 已关闭更新且未安装任何新软件(故意避免 java 运行时或其他已安装软件出现任何不稳定)。 今天早上 Eclip
我正在开发一个简单的 React.JS 前端部分。 我本质上有一个用于历史数据的浏览 SPA。该设计有一堆过滤器,我需要一次填充一个过滤器,从逻辑层次结构中的顶部过滤器开始。 我做了类似的事情:
我已经搞乱了我的代码有一段时间了......现在当我运行它并在菜单中单击第二个选项时,当我输入超过 15 个字符的密码时,我收到此错误?谁能看到我做错了什么?这可能是一些我无法发现的小事谢谢 错误:
我有一个正在尝试构建的“单词”链接列表,我创建了一个名为“add_to_mem”的函数,它将下一个单词添加到链接列表中。我对代码进行了几次检查,发现他工作了两次 - 一次当链接列表为 NULL 时,一
我遇到了这个错误 *** Error in `./main': double free or corruption (out): 0x000000000095c8a0 *** getPieces()定
我的 jni 代码中有 malloc 问题。该代码旨在让我访问 java 中的 exiv2 库。我尝试使用 sun 和 openjdk 1.6.0 虚拟机以及 1.7.0(测试版)虚拟机破坏代码。 错
使用 visual studio 2013,我一直在尝试运行下面的代码,但是当变量 vertexPointer 达到数字 7172 时,我以某种方式收到“堆已损坏”异常。有时我会收到错误消息:“未加载
是否有一个约定俗成的errno代码表明指定的文件已损坏(它不符合应有的文件格式)? 我正在编写文件解析器,但不知道要返回的最合适的代码是什么。总是有 EINVAL,虽然我希望有比这更具体的东西,因为它
我的 date.php 是 -
这可能是个愚蠢的问题,但我在运行 *.jar 包时随机出现以下错误。有时程序运行完美,有时会中断,将其输出到控制台: *** Error in 'java': double free or corru
当运行脚本来筛选 抓取 网页时,我遇到“zend_mm_heap 已损坏”。请让我知道如何解决此问题。 最佳答案 我假设您正在使用带有 mod_php 的 Apache 来回答这个问题。 当 apac
我有将十六进制字符串转换为字节数组的函数, BYTE* HexStrToByteArray(std::wstring hex_str) { int len = hex_str.size()*0
请不要为了这个把我钉在十字架上。我决定使用 char* 可能更好,因为我打算构建的字符串的大小已知。我还知道,如果 timeinfo->tm_hour 返回的不是 2 位数字,那么事情就会变得很糟糕。
我有一个包含 vector 的类 (foo)。 如果我尝试像这样遍历 vector 中的元素: for(vector::iterator it = foo.getVector().begin();
每当我从我的 Remote 中 pull 出时,我都会收到以下关于压缩的错误。当我运行手动压缩时,我得到了相同的结果: $ git gc error: Could not read 381378312
我是一名优秀的程序员,十分优秀!