简体   繁体   中英

UPLOAD MULTIPLE IMAGES FROM NODEJS TO PHP SERVER

NodeJS devs, I have a situation where I have to upload local images from NodeJS to PHP Server. There's no error, the request is successful 200 OK, but the picture does not appear in the PHP server.

Note: I am a nodeJS developer, don't have much experience in PHP.

Here's what wanna do:

In NodeJs, there's a list of files, Now one by one I want to append these files into formData, after that, I have to post this form data to the PHP server so that the pictures are uploaded to the PHP server,

In PHP server, at the first line, it is receiving the files from the post request and then with loop moving files with supported extension one by one to the upload directory and after the loop completes it sends back a response with an array containing files' download URL

Everything is working, I've consoled everything and everything has the perfect values and even the HTTPS POST request is successful but the PHP server there is no images, PHP server is not receiving files in the request so looks like multipart data is not working in NodeJs.

Looks like formData is not working properly in NodeJs because the same code works on client JS in the browser.

NodeJS:-

 const Axios = require('axios');
 const Fs = require('fs');
 const FormData = require('form-data');



 var formData = new FormData();

 //here allFiles is an array of object , each object contains 1 file with details like local file path ,name,size
for (var index = 0; index < allFiles.length; index++) { //Append multiple files to formData.

            let currentFile = allFiles[index]
            //createReadStream Retyrns fileData
            let fileWithInfo = await Fs.createReadStream(currentFile.uri)
            formData.append("files[]", fileWithInfo );

       }
 Axios.post('example.com/upload.php',formData,
     {
         headers: formData.getHeaders()
     })
     .then(d => console.log("DONE=>>>> ", d.data))
     .catch((f) => console.log('FAILED=>> ', f))

    });

PHP CODE:-

<?php
// Count total files
$countfiles = count($_FILES['files']['name']);

// Upload directory
$upload_location = "uploads/";

// To store uploaded files path
$files_arr = array();

// Loop all files
for($index = 0;$index < $countfiles;$index++){

   // File name
   $filename = $_FILES['files']['name'][$index];

   // Get extension
   $ext = pathinfo($filename, PATHINFO_EXTENSION);

   // Valid image extension
   $valid_ext = array("png","jpeg","jpg");

   // Check extension
   if(in_array($ext, $valid_ext)){

     // File path
     $path = $upload_location.$filename;

     // Upload file
     if(move_uploaded_file($_FILES['files']['tmp_name'][$index],$path)){
        $files_arr[] = $path;
     }
   }

}

echo json_encode($files_arr);
die;

https://github.com/form-data/form-data#buffer-getbuffer

const { readFile } = require('fs/promises');

for (let index = 0; index < allFiles.length; index++) {
  const currentFile = allFiles[index];
  const fileWithInfo = await readFile(currentFile.uri);
  formData.append('files[]', fileWithInfo);
}

axios.post('https://example.com/', formData.getBuffer(), formData.getHeaders());

// you have to send files as buffer

there is also solution with stream https://stackoverflow.com/a/53126159/8784402

const response = await axios({
        method: 'post',
        url: 'http://www.yourserver.com/upload',
        data: formData,
        headers: {
        'content-type': `multipart/form-data; boundary=${form._boundary}`,
        },
    });
Axios.post('example.com/upload.php', formData, {
  headers: formData.getHeaders()
})
.then(d => console.log("DONE=>>>> ", d.data))
.catch((f) => console.log('FAILED=>> ', f));

you are missing the data which is formData in your case from axios post request you can either directly pass formData or call formData.getBuffer().

Maybe my answer does not solve, but i advise few changes in PHP code. For sure, that keys in $_FILES array could not be numbers its better to use foreach instead of for. I allowed myself to change your code a bit to make it smaller

<?php
// Upload directory
$upload_location = "uploads/";

// To store uploaded files path
$files_arr = array();

// Valid image extension
$valid_ext = array("png","jpeg","jpg");

foreach($_FILES['files']['name'] as $key => $file) {
    if(
        in_array(pathinfo($_FILES['files']['name'][$key], PATHINFO_EXTENSION), $valid_ext)
        &&
        move_uploaded_file($_FILES['files']['tmp_name'][$key],$upload_location.$_FILES['files']['name'][$key])
    ) {
        $files_arr[] = $upload_location.$_FILES['files']['name'][$key];
    } else {
        //Only for debugging
        $files_arr[] = 'Not uploaded: '.$upload_location.$_FILES['files']['name'][$key];
    }
}

echo json_encode($files_arr);
die;
<?php
// Count total files
var_dump($_FILES['files']);

$countfiles = count($_FILES['files']['name']);
echo $countfiles;

// Upload directory
$upload_location = "uploads/";

// To store uploaded files path
$files_arr = array();

// Loop all files
for($index = 0;$index < $countfiles;$index++){
  echo $index;

   // File name
  $filename = $_FILES['files']['name'][$index];
  echo $filename;

   // Get extension
  $ext = pathinfo($filename, PATHINFO_EXTENSION);
  echo $ext;

   // Valid image extension
   $valid_ext = array("png","jpeg","jpg", "csv");

   // Check extension
   if(in_array($ext, $valid_ext)){

     // File path
     $path = $upload_location.$filename;

     // Upload file
     if(move_uploaded_file($_FILES['files']['tmp_name'][$index],$path)){
        $files_arr[] = $path;
     }
   }

}

/* echo json_encode($files_arr); */
die;
const Axios = require('axios');
 const Fs = require('fs');
 const FormData = require('form-data');

const allFiles = [
  {uri: 'my/Spark_Dataset/combin.csv'},
  {uri: 'my/Spark_Dataset/combine-csv.csv'},
  // {uri: 'C:\\Users\\my\\combine-csv.csv'}
];


(async function() {
  var formData = new FormData();

  //here allFiles is an array of object , each object contains 1 file with details like local file path ,name,size
  for (var index = 0; index < allFiles.length; index++) { //Append multiple files to formData.
    // console.log(index);

    let currentFile = allFiles[index]
    //createReadStream Retyrns fileData
    // console.log(currentFile);
    let fileWithInfo = await Fs.createReadStream(currentFile.uri)
    formData.append("files[]", fileWithInfo );
  }

  console.log(formData);

  Axios.post('http://localhost:8000/upload.php',
    formData,
    {
      headers: formData.getHeaders(),
      // 'Content-Type':'multipart/form-data',
    })
    .then(d => console.log("DONE=>>>> ", d.data))
    .catch((f) => console.log('FAILED=>> ', f))
})();
packages.json

"axios": "^0.20.0",
"form-data": "^3.0.0",
"fs": "0.0.1-security",

First i started local server by php -S localhost:8000

After running local server i run index.js file using node index.js
I tested the code locally and it was working correctly.

You missed allFiles.length param in loop in NodeJS code. Correct code will be

for (var index = 0; index < allFiles.length; index++) {

The PHP code is correct, but if you send an empty files array, it will not be an error and will be returned success response!

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