简体   繁体   English

将多张图片从 NodeJS 上传到 PHP 服务器

[英]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. NodeJS 开发人员,我有一种情况,我必须将本地图像从 NodeJS 上传到 PHP 服务器。 There's no error, the request is successful 200 OK, but the picture does not appear in the PHP server.没有错误,请求成功200 OK,但是PHP服务器中没有出现图片。

Note: I am a nodeJS developer, don't have much experience in PHP.注意:我是一个 nodeJS 开发者,在 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,在NodeJs中,有一个文件列表,现在我想将这些文件一个一个地附加到formData中,之后,我必须将此表单数据发布到PHP服务器,以便将图片上传到PHP服务器,

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在 PHP 服务器中,在第一行,它接收来自 post 请求的文件,然后循环将支持扩展名的文件逐个移动到上传目录,并在循环完成后发送一个包含文件的数组的响应下载地址

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.一切正常,我已经安慰了一切,一切都有完美的值,甚至 HTTPS POST 请求也成功了,但 PHP 服务器没有图像,PHP 服务器没有接收请求中的文件,所以看起来多部分数据不起作用Node.js。

Looks like formData is not working properly in NodeJs because the same code works on client JS in the browser.看起来 formData 在 NodeJs 中无法正常工作,因为相同的代码适用于浏览器中的客户端 JS。

NodeJS:- 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代码:-

<?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 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还有流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().您从 axios 发布请求中丢失了formData data ,您可以直接传递 formData 或调用 formData.getBuffer()。

Maybe my answer does not solve, but i advise few changes in PHP code.也许我的答案没有解决,但我建议对 PHP 代码进行一些更改。 For sure, that keys in $_FILES array could not be numbers its better to use foreach instead of for.可以肯定的是,$_FILES 数组中的键不能是数字,最好使用 foreach 而不是 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首先我通过php -S localhost:8000启动本地服务器

After running local server i run index.js file using node index.js运行本地服务器后,我使用node index.js运行 index.js 文件
I tested the code locally and it was working correctly.我在本地测试了代码,它工作正常。

You missed allFiles.length param in loop in NodeJS code.您错过了allFiles.length代码中循环中的allFiles.length参数。 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! PHP 代码是正确的,但是如果你发送一个空的 files 数组,它不会出错并且会返回成功响应!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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