Laravel 8 中使用JavaScript和JQuery点击Show按钮在模态框展示图片时出现404路径错误的技术求助
解决Laravel 8模态框图片404的问题
首先咱们先拆解你遇到问题的核心原因:
- Blade模板语法无法在外部JS文件中直接生效:你写的
{{ asset('storage/"+my_img_path+"') }}会被浏览器当成纯字符串处理——因为外部JS文件不会经过Laravel的Blade解析器,所以最终URL变成了{{ asset('storage/phone1.jpg') }},转义后就是控制台里看到的%7B%7B%20asset('storage/phone1.jpg')%20%7D%7D,自然触发404。 - 硬编码截取路径不可靠:
slice(30,40)是固定长度截取,一旦你的基础URL长度变化(比如域名、存储路径调整),就会截取错误的文件名,导致路径失效。
下面给你几个简单有效的解决方案,按推荐程度排序:
方案一:直接复用表格中图片的完整URL(最简单)
你的表格里的<img>已经通过Blade的asset()生成了正确的完整URL,完全不需要重新拼接,直接把这个URL拿来用就行:
修改你的show()函数:
function show(){ $(document).on('click','.show1',function(){ // 文本内容逻辑保持不变 const category_name_value = $(this).closest("tr").find('td:nth-child(2)').text(); const category_description_value = $(this).closest("tr").find("td:nth-child(3)").text(); // 直接获取表格中img的完整src const imageFullSrc = $(this).closest("tr").find("td:nth-child(4) img").attr("src"); // 打开模态框并赋值 $("#showmodal").modal('show'); $("#categoryname").val(category_name_value); $("#categorydescription").val(category_description_value); $("#categoryimage").attr('src', imageFullSrc); // 直接用现成的正确URL }) }
这个方案完全避开了路径拼接的坑,因为表格里的图片路径已经是Laravel生成的合法地址,直接复用即可。
方案二:在Blade页面定义基础URL,供JS调用
如果你确实需要自己拼接路径(比如后续要修改图片尺寸、格式),可以在Blade页面里先定义存储目录的基础URL,再让JS引用这个变量:
- 在
index.blade.php的<script>标签(外部JS之前)添加:
<script> // 由Blade解析后生成合法的存储基础URL,传给JS使用 const storageBaseUrl = "{{ asset('storage') }}"; </script>
- 修改外部JS的
show()函数:
function show(){ $(document).on('click','.show1',function(){ // 其他逻辑不变 const imageTd = $(this).closest("tr").find("td:nth-child(4) img"); // 更可靠的文件名获取方式:给表格img加data属性(推荐) // 先修改表格里的img:<img src="{{ asset('storage/'.$mycategory_data->image) }}" data-filename="{{ $mycategory_data->image }}" width="100" height="100"> const my_img_path = imageTd.data("filename"); const my_full_img_path = `${storageBaseUrl}/${my_img_path}`; // 后续赋值逻辑不变 $("#categoryimage").attr('src', my_full_img_path); }) }
用data属性存储文件名,比从URL截取更稳定,也更易维护。
方案三:修正Blade语法的错误用法(不推荐在外部JS使用)
如果你非要在JS里用Blade语法,只能在Blade页面的<script>标签里写,不能在外部JS文件中,而且要注意写法:
<script> function show(){ $(document).on('click','.show1',function(){ // ...其他逻辑 const my_img_path = $(this).closest("tr").find("td:nth-child(4) img").data("filename"); // 正确写法:Blade先解析asset基础路径,再拼接JS变量 const my_full_img_path = "{{ asset('storage') }}" + "/" + my_img_path; // ...后续逻辑 }) } </script>
但这种方式把JS逻辑和Blade混在一起,不利于代码维护,所以更推荐前两种方案。
最后提个小优化:你的show()函数里嵌套了$(document).ready(),其实没必要——因为你已经在页面底部调用show()了,而且$(document).on('click', ...)本身就是事件委托,不需要等DOM加载完成再绑定。
内容的提问来源于stack exchange,提问作者Virak Dev
相关产品推荐
相关产品推荐

