
本教程旨在解决在Laravel应用中,结合Krajee文件输入插件、AJAX和jQuery,通过表单提交而非插件自带上传按钮,实现文本输入与文件(如PDF)同时上传的常见问题。文章将详细阐述前端HTML、JavaScript配置及后端Laravel控制器中如何正确处理FormData和文件请求,确保数据完整送达并有效处理。
在现代Web开发中,文件上传是常见的需求,而结合文本表单数据一同提交则更为普遍。当使用像Krajee文件输入这样的强大前端插件时,开发者有时会遇到如何将其与自定义AJAX表单提交逻辑融合的挑战。本文将提供一个端到端的解决方案,指导您如何在Laravel项目中,利用jQuery和AJAX,通过标准的表单提交按钮,将包含文件和文本的表单数据安全高效地发送到后端控制器。
核心挑战在于确保浏览器将文件和所有表单字段打包成一个请求发送,并且Laravel能够正确识别并处理这些数据。
首先,我们需要一个包含文本输入框和Krajee文件输入字段的HTML表单。确保表单设置了enctype="multipart/form-data",这是文件上传的必要条件。同时,为了Laravel的安全机制,别忘了包含CSRF令牌。
<form method="POST" id="upload_form" enctype="multipart/form-data">
<!-- CSRF 令牌,Laravel 会自动生成一个隐藏的 input 字段 -->
@csrf
<label for="cliente_titulo">标题:</label>
<input id="cliente_titulo" type="text" class="form-control" name="cliente_titulo" required>
<label for="cliente_data">日期:</label>
<input id="cliente_data" type='text' class="form-control" name="cliente_data" autocomplete="off" required>
<label for="cliente_cliente">客户:</label>
<input id="cliente_cliente" type='text' name="cliente_cliente" class="form-control" autocomplete="off" required>
<label for="cliente_condominio">公寓:</label>
<input id="cliente_condominio" type="text" class="form-control" name="cliente_condominio" required>
<label for="cliente_pdf">上传PDF文件:</label>
<!-- Krajee 文件输入字段,name 属性用于后端获取文件 -->
<input id="cliente_pdf" name="pdf_file" type="file" class="file-loading"
data-allowed-file-extensions='["pdf"]' required>
<button id="confirm-create" type="submit" class="btn btn-success">
<strong>创建</strong><span class="glyphicon glyphicon-ok"></span>
</button>
</form>注意:
为了让Krajee插件与我们的自定义AJAX提交逻辑协同工作,我们需要对其进行初始化,但要禁用其自带的上传功能。
$(document).ready(function() {
$("#cliente_pdf").fileinput({
language: "zh", // 设置语言,根据需要调整
allowedFileExtensions: ['pdf'], // 允许上传的文件类型
maxFileCount: 1, // 最大文件数量
showUpload: false, // 禁用Krajee自带的上传按钮
showRemove: true, // 显示移除按钮
showCancel: false, // 禁用取消按钮
purifyHtml: true, // 清理HTML,提高安全性
// 以下是关键:移除或不设置 Krajee 的 uploadUrl 和 uploadAsync
// uploadUrl: "{{ url('create') }}", // 注释掉此行或确保不设置
// uploadAsync: true, // 注释掉此行或确保不设置
fileActionSettings: {
showUpload: false, // 在文件预览区禁用上传按钮
},
// 如果需要额外数据,通过FormData统一添加,而不是uploadExtraData
// uploadExtraData: function() { /* ... */ }
});
});关键点:
现在,我们将编写jQuery AJAX代码来监听表单的提交事件,收集所有数据(包括文件),并通过AJAX发送到Laravel控制器。
$(document).ready(function() {
// ... Krajee 文件输入初始化代码 ...
$('#upload_form').on('submit', function(e) {
e.preventDefault(); // 阻止表单默认的提交行为
// 使用 FormData 收集表单所有数据,包括文件
// $(this)[0] 获取原生的 DOM 元素
var formData = new FormData($(this)[0]);
// 确保 CSRF 令牌已包含在 formData 中。
// 如果 HTML 中使用了 @csrf,则 formData 会自动包含 _token。
// 如果没有,可以手动添加:
// formData.append('_token', $('meta[name="csrf-token"]').attr('content'));
// 或者从隐藏字段获取:
// formData.append('_token', $('input[name="_token"]').val());
$.ajax({
method: 'POST', // 请求方法为 POST
url: 'create', // 你的 Laravel 路由 URL
dataType: 'json', // 预期服务器返回的数据类型
cache: false, // 禁用缓存
processData: false, // 告诉 jQuery 不要处理数据
contentType: false, // 告诉 jQuery 不要设置 Content-Type 头部
data: formData, // 发送 FormData 对象
beforeSend: function() {
console.log('正在发送数据...');
// 可以在此处显示加载动画
},
success: function(response) {
console.log('上传成功!', response);
// 处理成功响应,例如显示成功消息、重定向等
alert('文件和数据已成功上传!');
},
error: function(xhr, status, error) {
console.error('上传失败!', xhr.responseText);
// 处理错误响应,例如显示错误消息
alert('上传失败:' + xhr.responseText);
}
});
});
});关键点:
最后,在Laravel控制器中,我们将接收并处理前端发送过来的数据和文件。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage; // 用于文件存储
class FlipbookController extends Controller
{
public function create(Request $request)
{
// 1. 验证请求数据
$request->validate([
'cliente_titulo' => 'required|string|max:255',
'cliente_data' => 'required|date_format:Y/m', // 假设日期格式为 YYYY/MM
'cliente_cliente' => 'required|string|max:255',
'cliente_condominio' => 'required|string|max:255',
'pdf_file' => 'required|mimes:pdf|max:10240', // 验证 PDF 文件,最大10MB
]);
// 2. 获取文本输入数据
$titulo = $request->input('cliente_titulo');
$data = $request->input('cliente_data');
$cliente = $request->input('cliente_cliente');
$condominio = $request->input('cliente_condominio');
// 可以通过 $request->all() 获取所有非文件输入数据
// $allInputs = $request->all();
// dd($allInputs); // 调试时查看所有文本数据
// 3. 处理文件上传
if ($request->hasFile('pdf_file')) { // 检查请求中是否存在名为 'pdf_file' 的文件
$file = $request->file('pdf_file'); // 获取 UploadedFile 实例
// 生成一个唯一的文件名
$fileName = time() . '_' . uniqid() . '.' . $file->getClientOriginalExtension();
// 将文件存储到 'public/pdfs' 目录下
// Storage::disk('public') 会将文件存放在 storage/app/public 目录下
// 要通过 URL 访问,需要运行 php artisan storage:link 创建软链接
$filePath = $file->storeAs('pdfs', $fileName, 'public');
// 可以获取文件的公共访问 URL
$fileUrl = Storage::url($filePath);
// 示例:将文件信息和表单数据保存到数据库
// YourModel::create([
// 'title' => $titulo,
// 'date' => $data,
// 'client' => $cliente,
// 'condominium' => $condominio,
// 'pdf_path' => $filePath, // 保存文件路径
// 'pdf_url' => $fileUrl, // 保存文件URL
// ]);
return response()->json([
'message' => '文件和数据上传成功!',
'data' => [
'titulo' => $titulo,
'data' => $data,
'cliente' => $cliente,
'condominio' => $condominio,
'pdf_path' => $filePath,
'pdf_url' => $fileUrl,
]
], 200);
} else {
// 如果没有文件上传,返回错误
return response()->json(['message' => '未找到上传的PDF文件。'], 400);
}
}
}关键点:
通过以上步骤,您已经成功构建了一个使用Krajee文件输入、AJAX和Laravel协同工作的表单上传系统。
重要注意事项:
遵循这些指南,您将能够构建一个稳定、安全且用户友好的文件上传功能。
以上就是使用Krajee文件输入、AJAX和Laravel实现文件与表单数据上传教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号