Laravel 在 Ajax 模式中调用 response()->file($pathToFile)
Posted
技术标签:
【中文标题】Laravel 在 Ajax 模式中调用 response()->file($pathToFile)【英文标题】:Laravel Calling response()->file($pathToFile) in a Ajax Modal 【发布时间】:2019-06-27 11:48:54 【问题描述】:因为我不喜欢“return response()->file($pathToFile);”时文件呈现给用户的默认方式被称为我想制作一个版本,其中文件不直接显示在网站的当前选项卡中,而是在弹出模式中 - 有点像在 Dropbox 中预览文件时的完成方式。
所以我所做的就是在我的视图中添加一个按钮,调用我的路线“preview_modal”此路线然后在我的 FileController 中调用我的“preview_modal”方法。 该方法在 Modal 中返回请求的文件。
但遗憾的是,当请求的文件的 Mimetype 不是“文本/*”类型的文件时,我会在我的模态中看到这种文本:
�PNG IHDRq�:sRGB���gAMA���a pHYs���o�d *IDATx^��r�6��~ Ob~��jn9�-��.Q�v˖-��ʥ��`ip���L��d��?�E����'0�0�M�afİ�3Ì6q�a��&�03b���aF����L&�V���H|�̏t[���kȲ�01����,�|�r�b��`����㙮�|:��/���� r/[X�>`�]��KH���5�Oޟa� ��N�A�|��KX��2�:γ�d ٢��,�
在这种情况下,它是一个被打开的 PNG。本文只是一个小例子。
我不知道我在看什么如果有人知道这是什么,我将不胜感激。 如果在 ajax 模态中没有调用“return response()->file()”,那么它对于同一个文件也可以正常工作。
按钮:
<button data-path=" route('files.preview_modal', $file) " class="button is-info load-ajax-modal" role="button" data-toggle="modal" data-target="#dynamic-modal">Preview</button>
Ajax 调用:
$.ajaxSetup(
headers:
'X-CSRF-Token': $('meta[name="_token"]').attr('content')
);
$('.load-ajax-modal').click(function ()
$.ajax(
type: 'GET',
url: $(this).data('path'),
success: function (result)
$('#dynamic-modal div.modal-body').html(result);
);
);
路线:
Route::get('preview_modal/file', 'FileController@preview_modal')->name('files.preview_modal');
preview_modal 方法:
public function preview_modal(File $file)
return response()->file(storage_path("$file->path"));
【问题讨论】:
【参考方案1】:最后试试这2个解决方案
storage_path("$file->path")
去掉双引号:storage_path($file->path)
因为你使用的是变量而不是字符串
也许您应该将图像转换为 base64。
$path = storage_path($file->path);
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
然后在 html 中使用它,享受美好的一天 :)
【讨论】:
感谢所有帮助,我现在无法尝试,但非常感谢! 将图像转换为 base64 文件对我有用。非常感谢您的帮助!【参考方案2】:您将返回整个 png 作为响应,只需返回图像名称,然后返回模态中使用的图像路径:
<img src="/images/ $imageName">
【讨论】:
我会这样做,但是图像存储在 laravel 的存储文件夹中,因为该文件属于一个用户。因此我无法以这种方式访问它,因为存储文件夹无法公开访问。我也无法公开文件,因为公用文件夹不允许进行身份验证检查。【参考方案3】:您只需创建符号链接即可公开访问存储文件夹
执行 php artisan storage:link
在 laravel 中创建符号链接
当您在 laravel 中创建符号链接时,它会创建 storage/app/public 文件夹到 public/storage 文件夹的符号链接。这意味着如果您想公开访问任何文件,请将所有文件放在 storage/app/public 文件夹中并像这样访问它
<img src="asset('storage/images/test.png')" >
这里的意思是文件 test.png 应该在 storage/app/public/images/ 文件夹中。
或者您可以创建自定义符号链接以存储在公共文件夹中,这样您就可以直接使用您的存储文件夹图像
abc.com/storage/images/picture.png
【讨论】:
但是如果某个文件在这个公用文件夹中,每个人都不能访问它吗?可以说这个文件是一张发票。我不希望它可供公众使用。或者被某种爬虫找到。【参考方案4】:$file = '../image.jpg';
$type = 'image/jpeg';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
readfile($file);
然后在您的 HTML 中,您将引用您的任何 laravel 路由 /outPutImage/ 就好像它是图像一样,因为这正是它输出的内容:
<img src="appurl.com/outPutImage" />
【讨论】:
然后我将再次收到相同的“错误”文本(...PNG IHDRq...:sRGB...gAMA...a pHYs...o...d)等等。但这一次,即使它不是通过 ajax 模态调用,而是直接调用它时 我做到了。这就是我得到的输出。以上是关于Laravel 在 Ajax 模式中调用 response()->file($pathToFile)的主要内容,如果未能解决你的问题,请参考以下文章
在 Ajax 调用中传递完整 URL 作为参数 - Laravel 5.1 路由