2010-09-14 42 views
15

Sử dụng nút v0.2.0 Tôi đang cố tìm nạp hình ảnh từ máy chủ, chuyển đổi hình ảnh thành chuỗi base64 rồi nhúng nó vào trang trong thẻ hình ảnh. Tôi có đoạn mã sau:Node.js base64 mã hóa hình ảnh đã tải xuống để sử dụng trong dữ liệu URI

var express = require('express'), 
request = require('request'), 
sys = require('sys'); 

var app = express.createServer(
    express.logger(), 
    express.bodyDecoder() 
); 

app.get('/', function(req, res){ 

    if(req.param("url")) { 
     var url = unescape(req.param("url")); 
     request({uri:url}, function (error, response, body) { 
      if (!error && response.statusCode == 200) { 

       var data_uri_prefix = "data:" + response.headers["content-type"] + ";base64,"; 
       var buf = new Buffer(body); 
       var image = buf.toString('base64'); 

       image = data_uri_prefix + image; 

       res.send('<img src="'+image+'"/>'); 

      } 
     }); 
    } 
}); 

app.listen(3000); 

Lưu ý: Mã này đòi hỏi "express" và "request". Và tất nhiên, node. Nếu bạn đã cài đặt npm, nó phải đơn giản như "npm install express" hoặc "npm install request".

Thật không may, điều này không hoạt động như mong đợi. Nếu tôi làm việc chuyển đổi với Google logo, sau đó tôi nhận được sau khi bắt đầu của chuỗi:

77 + 9UE5HDQoaCgAAAA1JSERSAAABEwAAAF8IAwAAAO +/ve +/ve +/vSkAAAMAUExURQBzCw5xGiNmK0t + U ++/vQUf77 + 9BiHvv70WKO +/vQkk77 + 9D

Tuy nhiên nếu tôi sử dụng trực tuyến Base64 encoder với cùng một hình ảnh, thì nó hoạt động hoàn hảo. Chuỗi bắt đầu như thế này:

iVBORw0KGgoAAAANSUhEUgAAARMAAABfCAMAAAD8mtMpAAADAFBMVEUAcwsOcRojZitLflOWBR + aBiGQFiipCSS8DCm1Cya1FiyNKzexKTjDDSrLDS

đâu tôi đi sai rằng điều này không làm việc một cách chính xác? Tôi đã thử rất nhiều triển khai base64 js khác nhau và tất cả chúng đều không hoạt động theo cùng một cách. Điều duy nhất tôi có thể nghĩ đến là tôi đang cố gắng chuyển đổi điều sai thành base64, nhưng tôi nên chuyển đổi điều gì nếu trường hợp đó xảy ra?

Trả lời

13

Sự cố đang mã hóa và lưu trữ dữ liệu nhị phân trong chuỗi javascript. Có một phần khá tốt về điều này dưới Bộ đệm tại http://nodejs.org/api.html.

Thật không may, cách dễ nhất để sửa lỗi này liên quan đến việc thay đổi yêu cầu npm. Tôi phải thêm response.setEncoding('binary'); trên dòng 66 ngay bên dưới var buffer; trong /path/to/lib/node/.npm/request/active/package/lib/main.js. Điều này sẽ hoạt động tốt đối với yêu cầu này nhưng không phù hợp với yêu cầu khác. Bạn có thể muốn hack nó để điều này chỉ được thiết lập dựa trên một số tùy chọn khác được thông qua.

Sau đó tôi đã thay đổi var buf = new Buffer(body) thành var buf = new Buffer(body, 'binary');. Sau đó, mọi thứ đều ổn.

Một cách khác để thực hiện việc này, nếu bạn thực sự không muốn chạm vào yêu cầu npm, sẽ chuyển vào một đối tượng thực hiện luồng có thể ghi trong đối số responseBodyStream để yêu cầu. Đối tượng này sau đó sẽ lưu trữ dữ liệu được truyền trực tiếp từ phản hồi trong bộ đệm của chính nó. Có lẽ có một thư viện thực hiện điều này ... tôi không chắc chắn.

Tôi sẽ rời khỏi đây ngay bây giờ, nhưng vui lòng bình luận nếu bạn muốn tôi làm rõ bất kỳ điều gì.

EDIT

Kiểm tra ý kiến.giải pháp mới tại http://gist.github.com/583836

+0

Cảm ơn, điều này có hiệu quả nhưng tôi thực sự không thích ý tưởng chỉnh sửa gói yêu cầu để làm cho nó hoạt động. Làm thế nào chính xác bạn sẽ thực hiện một đối tượng Writable Stream? Tôi không thể tìm ra cách để tạo ra nó. Bất kỳ trợ giúp sẽ được thực sự đánh giá cao! – betamax

+0

Tìm thấy triển khai luồng có thể ghi được tốt đẹp tại http://github.com/substack/node-bufferlist. Đây là phiên bản cập nhật của mã không cần phải sửa đổi thư viện yêu cầu: http://gist.github.com/583836. – bxjx

+0

phù hợp với bạn? – bxjx

8

Các mã sau (có sẵn tại https://gist.github.com/804225)

var URL = require('url'), 
    sURL = 'http://nodejs.org/logo.png', 
    oURL = URL.parse(sURL), 
    http = require('http'), 
    client = http.createClient(80, oURL.hostname), 
    request = client.request('GET', oURL.pathname, {'host': oURL.hostname}) 
; 

request.end(); 
request.on('response', function (response) 
{ 
    var type = response.headers["content-type"], 
     prefix = "data:" + type + ";base64,", 
     body = ""; 

    response.setEncoding('binary'); 
    response.on('end', function() { 
     var base64 = new Buffer(body, 'binary').toString('base64'), 
      data = prefix + base64; 
     console.log(data); 
    }); 
    response.on('data', function (chunk) { 
     if (response.statusCode == 200) body += chunk; 
    }); 
}); 

cũng nên tạo ra một dữ liệu URI mà không đòi hỏi bất kỳ module bên ngoài.

1

này làm việc cho tôi sử dụng yêu cầu:

const url = 'http://host/image.png'; 
request.get({url : url, encoding: null}, (err, res, body) => { 
    if (!err) { 
     const type = res.headers["content-type"]; 
     const prefix = "data:" + type + ";base64,"; 
     const base64 = body.toString('base64'); 
     const dataUri = prefix + base64; 
    } 
}); 

Không cần bất kỳ bộ đệm trung gian. Điều quan trọng là để thiết lập mã hóa thành null.

Các vấn đề liên quan