2013-06-28 5 views
0

http 응답 스트림의 이미지에서 노드 gm을 사용하는 간단한 이미지 조작 서비스를 작성했습니다. nodejs의 default transfer-encoding : chunked를 사용하면 문제가 없게됩니다. 그러나 content-length 구현을 시도하자 마자 nodej가 응답을 멈추거나 내용 길이가 일치하지 않는 오류가 발생합니다.nodejs gm 콘텐츠 길이 구현이 브라우저를 멈 춥니 다.

var image = gm(response); 
    // gm getter used to get origin properties of image 
    image.identify({bufferStream: true}, function(error, value){ 
     this.setFormat(imageFormat) 
     .compress(compression) 
     .resize(width,height); 

     // instead of default transfer-encoding: chunked, calculate content-length 
     this.toBuffer(function(err, buffer){ 
     console.log(buffer.length); 
     res.setHeader('Content-Length', buffer.length); 
     gm(buffer).stream(function (stError, stdout, stderr){ 
      stdout.pipe(res); 
     }); 
     }); 
    }); 

이 원하는 이미지와 잘 보이는 콘텐츠 길이를 뱉어하지만 브라우저는 제안 중단됩니다 : 여기

은 (변수로 인해 예에 생략 된) 문제가되는 코드의 요점이다 약간의 불일치 또는 다른 잘못된 것이 있다는 것입니다. 노드 1.9.0을 사용하고 있습니다.

nodejs gm 콘텐츠 길이 구현에 관한 비슷한 게시물을 보았지만이 정확한 문제는 아직 게시하지 않았습니다.

미리 감사드립니다.

+1

'length'보다는'buffer.byteLength'를 사용하는 것이 좋습니다. 근본적인 문제 *는 기본적으로 노드의 스트림 모듈 (특히'ReadableStream')에서 문제가되는 것으로 보입니다. 예상 길이 (실제로는'Content-Length')가 실제 스트림 내용보다 길어서 영원히 기다리는 경우입니다 그 여분의 데이터에 – James

답변

0

나는 나의 접근 방식을 바꾸었다. this.toBuffer()를 사용하는 대신 this.write (fileName, callback)를 사용하여 새 파일을 디스크에 저장 한 다음 fs.createReadStream (fileName)을 사용하여 읽고 응답에 파이핑합니다. 예 :

var filePath = './output/' + req.param('id') +'.' + imageFormat; 
this.write(filePath, function (writeErr) { 
    var stat = fs.statSync(filePath);       
    res.writeHead(200, { 
    'Content-Type': 'image/' + imageFormat, 
    'Content-Length': stat.size 
    }); 

    var readStream = fs.createReadStream(filePath); 
    readStream.pipe(res); 

    // async delete the file from filesystem 
    ... 
}); 

클라이언트로 돌아가려면 새로운 콘텐츠 길이를 포함하여 필요한 모든 헤더를 얻게됩니다.