如何将base64编码的内存映像作为文件参数进行POST

时间:2013-02-16 15:12:27

标签: node.js encoding base64

我有一个编码为base64字符串的图像,我正在尝试将POST作为另一个REST API(http://ocrapiservice.com/documentation/)的参数。

我不想将文件存储在磁盘上 - 我想将文件保存在内存中,因为最终我想在客户端使用getUserMedia创建图像,我可能会使用托管不允许直接文件IO的服务。

我遇到的问题是大多数示例我可以使用fs.createReadStream(somePath);从磁盘中找到发布的图像,例如 https://github.com/mikeal/request/blob/master/README.md#forms

我更喜欢使用像request库这样的库,但这可能是不可能的。

我现在的代码是:

var fs = require( 'fs' );
var path = require( 'path' );

var request = require( 'request' );
var WS_URL = 'http://api.ocrapiservice.com/1.0/rest/ocr';

function ocr( postData ) {
    var r = request.post(WS_URL, completed);
    var form = r.form();

    form.append('apikey', 'REMOVED');
    form.append('language', 'en' );
    form.append('image', postData );

    function completed(error, response, body) {
        console.log( body );
    }
}

// This works
ocr( fs.createReadStream(path.join(__dirname, 'example.png' ) ) );

// This does not work
// ignore that it's being read from a file (the next line)
var base64Str = fs.readFileSync( 'example.png' ).toString('base64'); 

var buffer = new Buffer(base64Str, 'base64');
ocr( buffer.toString( 'binary' ) );

form.append允许发送其他参数,因此如果需要设置其他标头,那么这是可能的。

我可以使用某种Stream包装吗?我已尝试使用此StringReader示例,可以将其修改为至少发送文件名和正确的内容类型。

如何将内存文件作为参数发布到Web服务?

更新

我修复/更新了上面的代码。

我从上面列出的REST API获得的响应是​​:

  

HTTP / 1.1 400错误请求

     

没有提供文件

这是我正在运行的实际代码: https://gist.github.com/leggetter/4968764

3 个答案:

答案 0 :(得分:0)

在流版本中,您正在处理文件的各个部分,但在base64Image版本中,您正在使用base64字符串。由于流版本有效,ocr API显然希望表单只包含二进制数据,因此您需要在发送之前解码base64数据。

// Reading straight from a Buffer.
var imageData = fs.readFileSync('example.png');
ocr( imageData );

// Reading from a new Buffer created from a base64 string.
var base64Image = '...';
ocr(new Buffer(base64Image, 'base64'));

另请注意,在您的示例代码中:

// This line:
var base64Image = new Buffer(imageData, 'binary').toString('base64');

// does the same thing as this, because 'imageData' is alreadya  Buffer
var base64Image = imageData.toString('base64');

答案 1 :(得分:0)

我确信您可以直接使用Buffer请求,而无需将其包装到Stream

它无效,因为您使用的编码不正确。如果缺少编码,readFileSync默认返回Buffer。缓冲区默认使用utf-8作为其编码。但是您之间使用了编码作为二进制文件,这与缓冲区中的编码不一致。

var imageData = fs.readFileSync('example.png');//After you get imageData 
var base64Image = imageData.toString('base64');    //base64 encoded string
var decodedImage = new Buffer(base64Image, 'base64');  //base64 encoded buffer
ocr (imageData);  //You can use the file directly
ocr (base64Image); //Or you can use either the base-64 string or the base64-buffer

在这里查看更多编码/解码详细信息 NodeJS base64 image encoding/decoding not quite working

答案 2 :(得分:0)

你应该能够使用我发起的base64-image-upload NPM包,因为我遇到了同样的问题。

这样做正是user568109概述的方法,从base64字符串创建缓冲区并对其进行POST。重要的是它抽象处理编码,MIME类型和请求标题,这将大大简化您的代码。