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 ::)