Загрузка изображений из React с помощью laravel api

У меня возникают проблемы с загрузкой файлов из ввода реакции с помощью API-интерфейса laravel. Я работаю с формой реакции. Моя форма и onSave следующие


const onSave = data => {
        // data.picture = imgs; here I tried changing the picture to event.target.files from the file input, didn't work either.
        axios.defaults.headers.common["Authorization"] = "Bearer " + token;
        axios
            .post(`/api/products/store`, data, {})
            .then(res => {
                console.log(res);
            })
            .catch(err => console.log(err));
    };

return (
<form onSubmit={handleSubmit(onSave)} encType="multipart/form-data">
    <input
        type="file"
        name="picture[]"
        label="Product Picture"
        onChange={handlePicInput}
        className={classes.inputFile}
        multiple
        />
//other inputs
</form>
);

мой почтовый запрос приводит к этому методу контроллера

 public function store(Request $request)
    {
        $imageNames = '';
        $pictures = (object) $request->file('picture');
        //$pictures = $request->allFiles();
        //$pictures = (object) $request->file('picture[]');
        //$pictures = (object) $request->files;
        foreach ($pictures as  $key => $picture) {
            /*WHEN I'M USING POSTMAN OR INSOMNIA, 
             this foreach loop is accessed but 
             the react form just skips the foreach completely */
            $imageNames = $imageNames . $picture->store('product_pictures', 'public') . ',';
        }

        $product = Product::create([
            'name' => $request->name,
            'prices_amountmax' => $request->prices_amountmax,
            'prices_amountmin' => $request->prices_amountmax,
            'brand' => $request->brand,
            'manufacturer' => $request->manufacturer,
            'weight' => $request->weight,
            'category_id' => $request->category_id,
            'stock' => $request->stock,
            'imageurls' => $imageNames
        ]);
        $product->save();
    }

Подводя итог, я тестировал загрузку изображений с помощью почтальона, он работает нормально, так что проблема должна быть в форме реакции? Спасибо за любую помощь


person Lotfi    schedule 23.02.2020    source источник


Ответы (2)


Для загрузки изображений с помощью js вы можете использовать FormData. Я не вижу вашего метода handlePicInput, чтобы понять, как обрабатывается изменение ввода, но, возможно, этот фрагмент поможет вам понять, что делать дальше.

function handlePicInput(event){
    let images = event.target.files
    let fd = new FormData()
    fd.append("images", images);
}

Затем вы можете добавить в fd другие значения и отправить через axios

axios.post(`/api/products/store`, fd)

Опять же, где разместить код и как обрабатывать другие входные данные, которыми вы должны управлять самостоятельно или предоставить больше данных

person Ruben Danielyan    schedule 23.02.2020
comment
Спасибо, похоже, сейчас это работает, но файлы имеют тип File (из javascript) .. как мне сделать их laravel UploadedFile? - person Lotfi; 24.02.2020
comment
Спасибо, все работает !, проблема только в том, что $ request- ›file ('picture'); может получить доступ только к одному файлу, поэтому, если вы передаете список файлов, вы не сможете получить к ним доступ по какой-то причине, я нашел обходной путь для этого без проблем, добавляя каждое изображение в 'fd' индивидуально - person Lotfi; 24.02.2020

Попробуйте отправить его как formData с несколькими файлами:

const onSave = data => {

  const formData = new FormData();
    for (let i in data) {
      if(i === 'picture[]'){
        for(let file of data[i]){
            formData.append('picture',file);
        }

      }else{
        formData.append(i, data[i])
      }  

    }
  // data.picture = imgs; here I tried changing the picture to event.target.files from the file input, didn't work either.
  axios.defaults.headers.common["Authorization"] = "Bearer " + token;
  axios
      .post(`/api/products/store`, formData, {})
      .then(res => {
          console.log(res);
      })
      .catch(err => console.log(err));
}; 

Я тестировал его с помощью бэкэнда Node / Express, и, похоже, он работает. «картинка» будет массивом файлов. Если ваш php-бэкэнд не распознает это правильно, попробуйте изменить formData.append ('изображение', файл) на formData.append ('изображение []', файл), но тогда вам также нужно будет изменить имя в ваш php.

person i.brod    schedule 23.02.2020