【问题标题】:UPLOAD MULTIPLE IMAGES FROM NODEJS TO PHP SERVER将多个图像从 NodeJS 上传到 PHP 服务器
【发布时间】:2020-10-14 20:11:53
【问题描述】:

NodeJS 开发者, 我有一种情况,我必须将本地图像从 NodeJS 上传到 PHP Server。 没有报错,请求成功200 OK,但是图片没有出现在PHP服务器中。

注意:我是nodeJS开发人员,对PHP没有太多经验。

以下是想做的事:

在NodeJs中,有一个文件列表,现在我想把这些文件一个一个追加到formData中,之后我要把这个表单数据发布到PHP服务器,这样图片才能上传到PHP服务器,

在 PHP 服务器中,在第一行,它从 post 请求中接收文件,然后循环将具有支持扩展名的文件逐个移动到上传目录,并在循环完成后发送回一个带有数组的响应包含文件的下载地址

一切正常,我已经安慰了一切,一切都有完美的值,甚至 HTTPS POST 请求也成功,但 PHP 服务器没有图像,PHP 服务器没有接收请求中的文件,所以看起来像多部分数据不能在 NodeJs 中工作。

看起来 formData 在 NodeJs 中无法正常工作,因为相同的代码在浏览器中的客户端 JS 上工作。

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

<?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;

【问题讨论】:

  • 现在作为临时解决方案我正在使用restler库,但它只能在1个请求中发送单个文件,我想要一个可以将多个文件上传到PHP服务器的解决方案。
  • 您是否测试过请求正在到达服务器

标签: javascript php node.js


【解决方案1】:

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

还有流的解决方案 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}`,
        },
    });

【讨论】:

【解决方案2】:

也许我的回答没有解决,但我建议对 PHP 代码进行一些更改。当然,$_FILES 数组中的键不能是数字,最好使用 foreach 而不是 for。我允许自己稍微更改您的代码以使其更小

<?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;

【讨论】:

    【解决方案3】:
    Axios.post('example.com/upload.php', formData, {
      headers: formData.getHeaders()
    })
    .then(d => console.log("DONE=>>>> ", d.data))
    .catch((f) => console.log('FAILED=>> ', f));
    

    您在 axios 发布请求中缺少 data,在您的情况下是 formData,您可以直接传递 formData 或调用 formData.getBuffer()。

    【讨论】:

    • 您好 Chandan,感谢您的回复,我为在 StackOverflow 上发布了一个特定的代码,因此错误地从 StackOverflow 中删除了 formData 但是原始代码包含 formData 并且仍然不起作用。
    【解决方案4】:
    <?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",
    

    首先我通过php -S localhost:8000启动本地服务器

    运行本地服务器后,我使用 node index.js 运行 index.js 文件
    我在本地测试了代码,它工作正常。

    【讨论】:

    • 你能显示你从服务器收到的响应吗?我也试过你的 JS 代码,一切都一样,但它仍然无法正常工作我收到一个空数组并且文件没有发送到 PHP,这是我的回复:i.postimg.cc/3xKfXfQS/Screenshot-2020-10-25-at-8-41-41-PM.png
    • 它对你有用,但对我不起作用我不知道为什么,如果你不介意你可以试试它是否也适用于图像?由于文件类型不同,我认为它对您有用。非常感谢您抽出宝贵时间为您提供帮助。
    • 你能分享一下你使用的是什么版本的php和node
    • PHP 版本 7.2.34 ,节点版本 12.18.2
    【解决方案5】:

    您在 NodeJS 代码的循环中错过了 allFiles.length 参数。 正确的代码将是

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

    PHP代码是正确的,但是如果你发送一个空的files数组,就不会出错,会返回成功响应!

    【讨论】:

      猜你喜欢
      • 2015-07-12
      • 2011-02-02
      • 2015-03-29
      • 2011-10-15
      • 1970-01-01
      • 2012-02-14
      • 2013-11-02
      相关资源
      最近更新 更多