Create a API Upload Multiple Image using Laravel + React

min read

Day 43/100 #100DaysOfCode #React #Laravel

Nay mình đi tìm hiểu về phần upload nhiều hình ảnh từ front-end (React) đến Back-end (Laravel), sau đó di chuyển các hình ảnh vào thư mục. Okay bắt đầu thôi nào các bạn!

# Backend 

Ở đây mình dùng Laravel 8 , các bạn có thể thử các phiên bản khác nhá, mình sẽ cài đặt một route để bắt sự kiện request từ react gửi lên, routes/api.php

<?php
// header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
// header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token, Authorization, Accept,charset,boundary,Content-Length');
// header('Access-Control-Allow-Origin: *');
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Route::post('upload-multiple-image',function(Request $request){
     $destinationPath = public_path('/upload/images/');
     if($request->hasFile('add_slide')) {
                    $allowedfileExtension=['pdf','jpg','png','jpeg'];
                    $files = $request->file('add_slide'); 
                    $errors = [];
                   
                    foreach ($files as $file) {      
                        $extension = $file->getClientOriginalExtension();
                        $check = in_array($extension,$allowedfileExtension);
                        if($check) {
                                $name = $file->getClientOriginalName();
                                $name = $date."_".trim($name);
                                $imagePath = $destinationPath . "/" . $name;
                                $image->move($destinationPath, $name);
                            
                        } 
                    }
                   return Response()->json(array("success"=>1));
          }
 

 });
 

Ở phần Backend các bạn dùng chung proxy thì sẽ không bị lỗi. "cors" , còn ở trong trường hợp backend là http://localhost:8000 và frontend http://localhost:3000, khi gửi request từ frontend ta sẽ gặp một số lỗi điểm hình như là "cors"

Chính vì thế bạn cần cài đặt thư viện fruitcake/laravel-cors trong Laravel nhé, còn không bạn sử dụng 3 đoạn code thần thánh sau, add vào đầu file routes/api.php

header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token, Authorization, Accept,charset,boundary,Content-Length');
header('Access-Control-Allow-Origin: *');

#FrontEnd

Trong phần xử lý front-end(React) mình cũng tải project react về và sử dụng fetch hoặc axios để request yêu cầu đến Backend(Laravel) thôi

1. Viết function để xử lý chọn nhiều file, sao đó lưu các file hình đó vào State

2. Sau khi có file hình trong State rồi, thì ta dùng FormData để lưu giá trị State đó, gửi đến Laravel(backend)

* Function Choose Multiple Image


const [chooseFile, setChooseFile] = useState([]);

const selectMultipleImg = (e) => {
    const imgLength = e.target.files;
    if (imgLength.length > 0) {
     
      let choose_file = chooseFile;
      for (let i = 0; i < imgLength.length; i++) {
        if (e.target.files[i]) {
          let file = e.target.files[i];

          const reader = new FileReader();
          reader.onloadend = async () => {
            let img = reader.result;
            const index = choose_slide.findIndex((item) => item == img);
            if (index == -1) {
             
              choose_file = [...choose_file, file];
             
              setChooseFile(choose_file);
            }
          };
          reader.readAsDataURL(file);
        }
      }
    }
  };

Đoạn code trên ta dùng chọn nhiều file hình ảnh, nó sẽ kiểm tra xem, tấm hình ảnh đó có trong State chưa, nếu chưa, thì thêm hình đó vào State

* Function onSubmit Form

const onAddPost =  (e) => {
    e.preventDefault();
   
     const _formdata = new FormData();
     _formdata.append("_method","POST");//if form edit => "PUT", add=>"POST",delete=>"DELETE"
      chooseFile.forEach((image_file) => {
      _formdata.append('add_slide[]', image_file);
      });

     //console.log( _formdata.getAll("add_slide[]"))

     const requestOptions = {
            method:'POST',
            body: _formdata,
      };
    fetch(`http://127.0.0.1:8000/api/upload-multiple-image`,requestOptions)
    .then(res=>res.json())
    .then(result=>{
      console.log(result)
    })
    // axios.post(`http://127.0.0.1:8000/api/upload-multiple-image`,_formdata).then(res=>{
    //     console.log(res)
    //   })
    
  }
  

Đoạn code bên trên,  mình sẽ dùng FormData để chứa các file hình ảnh, sao đó request đến Backend(Laravel) để bên kia xử lý thôi

Sử dụng forEach để lặp các file hình trong State , append đến FormData, ở đây mình nhớ chú ý là add_slide phải giống với add_slide bên backend để nó có thể nhận biết nhé

 chooseFile.forEach((image_file) => {
      _formdata.append('add_slide[]', image_file);
      });

* Form HTML 

<form onSubmit={onAddPost} encType='multipart/form-data'>

   <input type="file"  multiple onChange={selectMultipleImg} />
<button type="submit" name="submit"> Add</button>
</form>

 

Okay vậy là xong ::)

x

Ủng hộ tôi bằng cách click vào quảng cáo. Để tôi có kinh phí tiếp tục phát triển Website!(Support me by clicking on the ad. Let me have the money to continue developing the Website!)