【问题标题】:How to POST base64 encoded in-memory image as file parameter如何将 base64 编码的内存图像作为文件参数发布
【发布时间】:2013-02-16 15:12:26
【问题描述】:

我有一个编码为 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

【问题讨论】:

    标签: node.js encoding base64


    【解决方案1】:

    在流版本中,您正在处理文件的片段,但在 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');
    

    【讨论】:

    • 我已经更新了发送二进制数据的问题(据我所知),并提供了一个指向我正在执行的代码的链接。
    • 为什么加.toString('binary')?这样做完全不同。
    【解决方案2】:

    我相信您可以直接使用Buffer 进行请求,而不必将其包装成Stream

    它不起作用,因为您使用了不正确的编码。如果编码不存在,readFileSync 默认返回Buffer。 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

    【讨论】:

      【解决方案3】:

      你应该可以使用我创建的base64-image-upload NPM 包,因为我遇到了同样的问题。

      这正是 user568109 概述的方法,从 base64 字符串创建一个缓冲区并发布它。重要的部分是它抽象了对编码、MIME 类型和请求标头的处理,这将大大简化您的代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-25
        • 2019-09-17
        • 1970-01-01
        • 2012-03-23
        • 1970-01-01
        • 2016-05-07
        • 2014-01-19
        相关资源
        最近更新 更多