vant+thinkphp实现文件上传功能
- 前端
- thinkphp后端
- 测试
前端
vue3 +vant
代码实现
fileList 预览文件列表,具体可以参考官方文档
let config = {
headers: {
//添加请求头
“Content-Type”: “multipart/form-data”,
},
};
需要以form-data的形式上传文件,所以在发起请求之前需要配置一个请求头
<script setup>
import {ref } from "vue";
import axios from "axios";
import { showToast } from "vant";
const fileList = ref([
// 如果图片 URL 中不包含类型信息,可以添加 isImage 标记来声明
]);
const afterRead = (file) => {
// 创建 FormData 对象
const formData = new FormData();
// 遍历所有选定的文件并附加到 FormData 对象中
formData.append("files[]", file.file);
// 上传文件的目标 URL
const uploadUrl = "http://127.0.0.1:8000/upload";
let config = {
headers: {
//添加请求头
"Content-Type": "multipart/form-data",
},
};
// 发送 POST 请求
axios
.post(uploadUrl, formData, config)
.then((response) => {
// 处理上传成功的情况
showToast("上传成功");
console.log("文件上传成功:", response.data.data);
})
.catch((error) => {
// 处理上传失败的情况
showToast("文件上传失败")
console.log("文件上传失败,请稍后重试", error);
});
};
</script>
<template>
<div class="mine">
<!-- 设置 multiple 属性允许多文件选择 -->
<van-uploader :after-read="afterRead" multiple v-model="fileList" />
</div>
</template>
thinkphp后端
修改config/filesystem.php
<?php
return [
// 默认磁盘
'default' => env('filesystem.driver', 'local'),
// 磁盘列表
'disks' => [
'local' => [
'type' => 'local',
'root' => app()->getRuntimePath() . 'storage',
],
'public' => [
// 磁盘类型
'type' => 'local',
// 磁盘路径
'root' => app()->getRootPath() . 'public/uploads',
// 磁盘路径对应的外部URL路径
'url' => '/uploads',
// 可见性
'visibility' => 'public',
],
// 更多的磁盘配置信息
],
];
新建一个upload类用来实现文件上传的逻辑
<?php
namespace app\controller;
use think\Facade\Request;
use app\BaseController;
class Upload extends BaseController
{
public function index()
{
$files = request()->file('files');
foreach ($files as $file) {
$ext = $file->getOriginalExtension();
//不同文件,储存不同的文件夹
$folder = config('filesystem.disks.folder') . '/uploads/' . $ext; //以文件后缀名作为存文件的存放目录
if (!file_exists($folder))
mkdir($folder, 0700, TRUE); //如果文件夹不存在,则创建
$savename = \think\facade\Filesystem::disk('public')
->putFile('', $file, 'md5'); //上传文件,得到上传之后的文件名称
if (!$savename) {
return json([
"code"=>400,
"msg"=>"文件上传失败",
"data"=>null
]);
} else {
$savename = '' . str_replace("\\", "/", $savename);
if ($savename) {
return json([
"code" => 200,
"msg" => "文件上传成功",
"data" => Request::domain() . '/uploads/' . $savename,
//因为要返回给前端网址,这里要加上域名 Request::domain()
]);
}
}
}
}
}
上传成功返回图片的url地址,可以用来当做用户的头像,或者商品的图片等
设置路由
Route::post("/upload","upload/index");
设置跨域请求
<?php
namespace app\middleware;
class CorsMiddleware
{
public function handle($request, \Closure $next)
{
// 设置允许跨域的域名,* 表示允许任何域名访问
$origin = '*';
// 设置允许的请求方法
$methods = 'GET, POST, PUT, DELETE';
// 设置允许的请求头字段
$headers = 'Origin, X-Requested-With, Content-Type, Accept';
// 设置响应头
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: *");
header("Access-Control-Allow-Headers: *");
// 对预检请求进行处理
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Max-Age: 86400'); // 预检请求的有效期,单位秒
header("Content-Length: 0");
header("Content-Type: text/plain");
exit();
}
// 继续处理请求
return $next($request);
}
}
在middleware.php中挂载中间件路由
<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class
\app\middleware\CorsMiddleware::class
];
测试
用postman上传测试
上传成功返回上传图片的url地址
在vue中测试