2014-03-19 32 views
5

我正在嘗試將請求的二進制正文寫入文件並失敗。該文件在服務器上創建,但我無法打開它。我在Ubuntu上遇到'致命錯誤:不是png'。下面是我如何提出請求:使用node.js寫入二進制數據的問題

curl --request POST --data-binary "@abc.png" 192.168.1.38:8080 

這裏是我如何試圖將它與文件一起保存。第一個片段是附加的所有數據一起的中間件,並且第二個是請求處理程序:

中間件:

app.use(function(req, res, next) { 
    req.rawBody = ''; 
    req.setEncoding('utf-8'); 
    req.on('data', function(chunk) { 
    req.rawBody += chunk; 
    }); 
    req.on('end', function() { 
    next(); 
    }); 
}); 

處理程序:

exports.save_image = function (req, res) { 
    fs.writeFile("./1.png", req.rawBody, function(err) { 
    if(err) { 
     console.log(err); 
    } else { 
     console.log("The file was saved!"); 
    } 
    }); 
    res.writeHead(200); 
    res.end('OK\n'); 
}; 

這裏的一些信息可能幫助。在中間件中,如果我記錄rawBody的長度,它看起來是正確的。我真的被困在如何正確保存文件。我需要的只是朝正確的方向發展。

謝謝。

+0

你能否澄清 「失敗」?文件是否存在於服務器上,但內容不正確?服務器上文件是否完全不存在?你有錯誤信息嗎? –

+0

編輯我的問題。 –

回答

4

這是一個完整的快速應用程序的作品。我用curl --data-binary @photo.jpg localhost:9200打它,它工作正常。

var app = require("express")(); 
var fs = require("fs"); 
app.post("/", function (req, res) { 
    var outStream = fs.createWriteStream("/tmp/upload.jpg"); 
    req.pipe(outStream); 
    res.send(); 
}); 
app.listen(9200); 

我只是將請求直接傳送到文件系統。至於你的實際問題,我的第一個猜測是req.setEncoding('utf-8');,因爲utf-8用於文本數據而不是二進制數據。

+0

是的,它工作。但是,在某些情況下,我只能看到部分圖像。這通常發生在遠程連接上。 –

+0

那麼,這可能不是您可以在代碼中修復的問題。如果網絡沒有傳送數據包,那麼在應用程序代碼中無法完成的任何事情都會奇蹟般地合成它們。你需要在那裏挖掘到底發生了什麼問題,但這可能不是一個代碼問題。 –

+0

也許您應該檢查傳入數據的內容長度標頭,如果不匹配拒絕。 –

0

要解決您的問題:我與@Peter Lyons,即錯誤可能是req.setEncoding('utf-8');行。

我知道以下問題不直接提出您的問題,但建議使用Express.js提供的req.files功能替代您正在使用的功能。

if(req.files.photo & & req.files.photo.name){ //獲取文件的臨時位置。 var tmp_path = req.files.photo.path;

// set where the file should actually exists - in this case it is in the "images" directory. 
var target_path = './public/profile/' + req.files.photo.name; 

// Move the file from the temporary location to the intended location. 
fs.rename(tmp_path, target_path, function (error) { 
    if (!error) { 
     /* 
     * Remove old photo from fs. 
     * You can remove the following if you want to. 
     */ 
     fs.unlink('./public/profile/' + old_photo, function() { 
      if (error) { 
       callback_parallel(error); 
      } 
      else { 
       callback_parallel(null); 
      } 
     }); 
    } 
    else { 
     callback_parallel(error); 
    } 
}); 

}

+0

這也是我的偏好,但我必須使用提供給我的外部數據源,這是我無法控制的。謝謝你的回答。 –

+0

如果客戶端使用enctype =「multipart/form_data」的http表單,然後在該表單上發佈提交,則會定義req.files屬性。如果客戶使用了不同的機制,例如AJAX調用,那麼不會有這樣的屬性集。 – Alex