久久写一次档案上传都要再去爬文?,乾脆自己笔记起来!!
一、Vue 前端
1. 隐藏Input的按钮
HTML内建的上传Input
很丑,所以我都把它隐藏起来,要用时再自己手动去触发他。为了触发他因此要给他一个 ref
的值,这样我们才能透过 $refs
直接去接触DOM
。
<input type="file" style="display: none" ref="fileInput" >
2. 自己做一个上传按钮
这边我是用 Quasar 框架的按钮,用原生的 button
套 CSS
也是可以啦。主要是让他看起来像上传的按钮就好~这边要做的事情就是按下去让他去触发原本按下 Input
时的事件。
<q-btn @click="$refs.fileInput.click()">上传档案</q-btn>
3. 触发上传事件
选择好档案后为了要让他能触发上传的事件,这边要再改一下刚刚的 Input
,要在后面补上 v-on:change
。
<input type="file" style="display: none" ref="fileInput" @change="uploadFile()">
4.上传事件的Function
接着再底下的 script
里的 methods
新增一个上传的方法。对了,这里会透过 Axios
来把档案丢给 Laravel。
<template> <q-page class="flex flex-center"> <q-btn @click="$refs.fileInput.click()">上传档案</q-btn> <input type="file" style="display: none" ref="fileInput" @change="uploadFile"> </q-page></template><script>import axios from 'axios'export default { methods: { uploadFile () { // 拿取档案 const file = this.$refs.fileInput.files[0] // 然后自己建立一个表单来放要上传的资料 // 也可以顺便带其他资料例如 userId const form = new FormData() form.append('file', file) form.append('userId', 'test1234') // 上传到后端伺服器 axios.post('https://后端网址', form) } }}</script>
二、Laravel 后端
这边要用到 Laravel 内建的 Storage
功能,所以我们在一个 Controller 的最上面引入他:
use Illuminate\Support\Facades\Storage;
之后开始来处理刚刚丢进来的档案(这边假设Router都设定好了)
1.首先在 Controller 里面开一个 function
public function postFile (Request $req) {}
2.我们刚刚的 file 会跑到 $req[‘file’] 这边
像是图片的话可以直接用 Storage
的 put
方法存就好,因为他会帮我们把档名变成乱数,可以不用花时间再去写怕档名重複的Code。这里只要给他要储存的路径就好。
$storagePath = Storage::put('/public', $req['file']);
要知道刚刚程式自己存的档名是什么,可以透过 basename
去拿档名:
$fileName = basename($storagePath);
而乱数的档名会像这样:61DsAms1VuHcMq1wcFx7S8cEHJA86SwoHPTTRUZV.png
3.档案存去哪里!?
路径不填的话档案会存在 storage/app
底下
如果要让其他人可以从网站存取那就要建立一个与 public 的超连结
php artisan storage:link
这样在 public/storage
底下就可以看到 storage/app/public
底下的东西啰
所以要从网站上看刚刚上传的网址就会是
https://你的Laravel网址/storage/刚刚上传的档名
4. 完整的程式码
<?phpnamespace App\Http\Controllers;use App\Http\Controllers\Controller;use Illuminate\Support\Facades\Storage;class FileController extends Controller{ public function postFile (Request $req) { $storagePath = Storage::put('/public', $req['file']); $fileName = basename($storagePath); // 接下来可以把档名存进资料库等等 // ... }}
*本文章同步发表于medium