简体   繁体   中英

Node/Request Error: “Processing POST Request: No Content-Type”

I have a front end Canvas that I transform into a png file that I need to POST to a third party vendor's api. It passes back to node as a base64 file and I decode it, but when I attempt the upload, it gives me the following error:

Problem processing POST request: no Content-Type specified

However, I am clearly specifying the content type in my POST call. My end goal is to upload the file to my vendor's API.

Here are the key front end aspects:

var canvasImage = document.getElementById("c");
        var img = canvas.toDataURL({
            multiplier: canvasMultiplier
        });

var fileTime = Date.now();
            var myFileName = $scope.productCode + fileTime;
            $scope.filenameForVendor = myFileName;
            var filename = $scope.filenameForVendor;

$http.post('/postVendor', { filename: filename, file: img }).success(function (data) {
                console.log("Uploaded to Vendor");

Here is the backend POST:

app.post('/postVendor', function (req, res, next) {
    var filename = req.body.filename;
    var file = req.body.file;
    fileBuffer = decodeBase64Image(file);

    request({
        url: "http://myvendorapi/ws/endpoint",
        method: "POST",
        headers: {
            'contentType': fileBuffer.type
        },
        body: fileBuffer.data
    }, function (error, response, body) {
        console.log(response);
    });
})

// Decode file for upload
function decodeBase64Image(dataString) {
    var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/),
        response = {};

    if (matches.length !== 3) {
        return new Error('Invalid input string');
    }

    response.type = matches[1];
    response.data = new Buffer(matches[2], 'base64');

    return response;
}

I can POST using AJAX on the front end, but because of CORS and the vendor blocking all but server side calls to the endpoints (and they don't have JSONP), I can't use this. They are allowing my IP through for testing purposes so only I can make this work from my machine:

var send = function (blob) {
 var fileTime = Date.now();
            var myFileName = $scope.productCode + fileTime;
            $scope.filenameForVendor = myFileName;
            var filename = $scope.filenameForVendor;
            var formdata = new FormData();
            formdata.append('File1', blob, filename);

            $.ajax({
                url: 'http://myvendorapi/ws/endpoint',
                type: "POST",
                data: formdata,
                mimeType: "multipart/form-data",
                processData: false,
                contentType: false,
                crossDomain: true,
                success: function (result) {
                    console.log("Upload to Vendor complete!");

// rest of code here/including error close out
}

 var bytes = atob(dataURL.split(',')[1])
        var arr = new Uint8Array(bytes.length);
        for (var i = 0; i < bytes.length; i++) {
            arr[i] = bytes.charCodeAt(i);
        }
        send(new Blob([arr], { type: 'image/png' }));

Update:

I realized that contentType should be 'content-type'. When I did this, it creates an error of no boundary specified as I am trying multipart-form data (which I did all wrong). How can I pass formData to Node for uploading?

Update 2:

Per the advice offered, I tried using multer but am getting an ReferenceError: XMLHttpRequest is not defined.

Client side:

   var fileTime = Date.now();
            var myFileName = $scope.productCode + fileTime;
            $scope.filenameForVendor = myFileName;
            var filename = $scope.filenameForVendor;
            var formdata = new FormData();
            formdata.append('File1', blob, filename);

            $http.post('/postVendor', formdata, { transformRequest: angular.identity, headers: { 'Content-Type': undefined } }).success(function (data) {

Server side:

app.post('/postVendor', function (req, res, next) {
    var request = new XMLHttpRequest();
    request.open("POST", "http://myvendorapi.net/ws/endpoint");
    request.send(formData);
})

Why do you base64 encode the file?

You can upload raw file to your Node using FormData and you will not have to decode anything.

Front end

...
var request = new XMLHttpRequest(); 
request.open('POST', 'http://node.js/method'); 
request.send(formData); // vanilla 

--- or ---

...
$http.post('http://node.js/method', formData, { 
  transformRequest: angular.identity, 
  headers: {'Content-Type': undefined} 
}); // angular

Back end

Just install request .

...
var request = require('request');
app.post('/method', function (req, res, next) {
  // if you just want to push request you don't need to parse anything
  req.pipe(request('http://vendor.net')).pipe(res);
}) // express

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM