我有一个输入文件类型为隐藏的表单。图像标签作为可点击的触发器来选择文件本身,用 js 来触发它(有效),但我想在选择图像时自动发出 PUT 请求,而不必单击表单上的提交按钮,每次在输入字段上更改图像时。我为此使用了 ajax,但在处理请求的控制器端点上,我似乎没有任何文件。不过,如果我将其他字段(例如文本)放入控制器中,它们似乎可以通过请求传入控制器就好了。
我的路线:
Route::put('/coins/image/{key}', [CoinController::class, 'image'])->name("coins.image");
我的控制器(还没有实际的图像更新代码;只是我正在检查文件):
public function image(int $key)
{
dump(request()->file('file'));
dump(request()->file);
dump(request());
}
以下代码段中的我的 HTML 和 JS:
function promptImageForUpload(elemId)
{
$('#' + elemId).click();
}
function uploadImage(event, imgId, key)
{
event.preventDefault();
var inputElem = event.target;
var imageFile = inputElem.files[0];
var imgElem = $('#' + imgId);
var form = $(inputElem).parent();
var formData = new FormData(form[0]);
formData.append('file', imageFile);
$.ajax({
url: "/coins/image/" + key,
type: "PUT",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: formData,
enctype: 'multipart/form-data',
processData: false,
contentType: false,
success: function(response) {
var reader = new FileReader();
reader.onload = function(e) {
imgElem.attr("src", e.target.result);
};
reader.readAsDataURL(imageFile); // convert to base64 string
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card-body">
<form data-key="0" id="coin-header-0_form" method="POST" action="#" enctype="multipart/form-data">
<input type="file" name="file" id="coin-header-0_file" style="z-index:-1; width: 100%; height: 100%; display: none;" onchange="uploadImage(event, 'coin-header-0_preview', 0)">
<input type="hidden" name="_method" value="PUT">
<meta name="csrf-token" content="7c3s2NmosdK9qzrS10xGAB0rYXw5g41azRjcmPQC">
<img src="http://snapbuilder.com/code_snippet_generator/image_placeholder_generator/60x40/007730/DDDDDD/this%20pict" width="50px" height="50px" alt="icon" id="coin-header-0_preview" onclick="promptImageForUpload('coin-header-0_file');">
</form>
</div>
现在,我在 ajax 成功时强制更新图像的预览,而不是在成功更新时从更新的实体中检索它,以避免第二次查询。
我将方法设置为 PUT 以在 ajax 请求中进行欺骗,并且 xsrf 令牌也设置了标头。 Enctype 也设置为文件的 multipart/form-data。我不知道为什么我在请求中的任何地方都看不到上传的文件。
使用 Laravel 框架 8.25.0,jquery 3.5.1。
如果需要更多信息,请告诉我,任何人。 我无法在任何有关此主题的 stackoverflow 条目或其他地方找到任何解决方案。 非常感谢任何帮助,因为我真的不知道如何在调试方法中查看它。
答案 0 :(得分:0)
HTML 表单不支持 PUT
、PATCH
或 DELETE
操作。因此,在定义从 HTML 表单调用的 PUT
、PATCH
或 DELETE
路由时,您需要向表单添加隐藏的 _method
字段。与 _method
字段一起发送的值将用作 HTTP 请求方法:
<form action="/foo/bar" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
您可以使用 method_field 助手来生成 _method 输入:
{{ method_field('PUT') }}
同样,这个检查也可能影响ajax表单。然后在您的表单中切换到 POST 方法并设置 PUT 参数使其工作。