AJAX请求返回403访问被拒,文件夹权限正常仍异常
403错误排查:Hostinger上AJAX图片画廊组件失效问题
我的网站部署在Hostinger平台,多个页面使用自定义AJAX/JS组件从服务器图片文件夹生成图片画廊。近期该组件突然在Chrome、Edge、Firefox中失效,未对网站做任何改动,但所有调用该组件获取图片的页面均返回403错误。
控制台错误输出
Status 403 Forbidden VersionHTTP/2 Transferred1.01 kB (699 B size) Referrer Policystrict-origin-when-cross-origin cache-control private, no-cache, no-store, must-revalidate, max-age=0 content-length 699 content-security-policy upgrade-insecure-requests content-type text/html date Sat, 12 Nov 2022 16:29:30 GMT platform hostinger pragma no-cache server LiteSpeed X-Firefox-Spdy h2 Accept */* Accept-Encoding gzip, deflate, br Accept-Language en-US,en;q=0.5 Connection keep-alive Host cameronnelson.net Referer https://cameronnelson.net/pages/asphalt.html Sec-Fetch-Dest empty Sec-Fetch-Mode cors Sec-Fetch-Site same-origin TE trailers User-Agent Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0 X-Requested-With XMLHttpRequest
画廊组件代码(gallery.js)
class Gallery extends HTMLElement { constructor() { super(); } connectedCallback() { this.innerHTML = ` <div class='card-columns' id='gallery_header' style='column-count:1;'></div> <div class='card-columns'> <div id='gallery'></div> </div> `; var src = this.getAttribute('src'); var title = this.getAttribute('title'); var text = this.getAttribute('text'); $(document).ready(function() { $.ajax({ url : src, success: function (data) { if((title != null) || (text != null)) { var title_card = ` <div class='card'> <div class='card-body' style='text-align:justify'>` + (title != null ? `<div class='card-title'>` + title + `</div>`:'') + (text != null ? `<div class='card-text'>` + text + `</div>`:'') + `</div> `; $("#gallery_header").append( title_card ); } $(data).find("a").attr("href", function (i, val) { if( val.match(/\.(jpe?g|png|gif)$/) ) { var card = ` <div class='card clickable'> <a data-fancybox='gallery' href='`+ val + `'> <img class='card-img-top' src='`+ val + `'/> </a> </div> `; $("#gallery").append( card ); } }); } }); }); } } customElements.define('gallery-component', Gallery);
已尝试的解决步骤
- 检查图片文件夹(如
public_html/images/[子文件夹])权限,为所有用户开启读取/写入/执行权限,问题仍存在 - 本地服务器测试组件功能正常
- 排查
.htaccess文件,未创建过自定义.htaccess - 尝试用PHP替代JS实现页面,同样返回403错误
- 联系Hostinger客服,对方表示不清楚相关服务器变更
建议解决方案
1. 配置目录专属.htaccess
Hostinger默认可能限制了目录浏览或拦截AJAX请求,可在图片目录(如public_html/images)新建.htaccess文件,添加以下规则:
# 允许目录列表 Options +Indexes # 允许AJAX请求访问目录 <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTP_X_REQUESTED_WITH} XMLHttpRequest RewriteRule ^ - [L] </IfModule>
2. 排查服务器安全策略
Hostinger可能启用了ModSecurity或LiteSpeed防护规则,误拦截了目录列表请求:
- 登录Hostinger面板,找到安全设置模块,临时关闭ModSecurity测试是否恢复正常
- 重新提交工单,要求客服排查是否有针对目录AJAX请求的拦截规则
3. 改用PHP接口返回图片列表
绕过直接请求目录的方式,编写简单PHP脚本读取图片并返回JSON格式列表:
<?php // get-images.php $targetDir = $_GET['dir'] ?? ''; // 验证目录合法性,防止路径遍历 $allowedDirs = array('images/asphalt', 'images/other-folder'); if (!in_array($targetDir, $allowedDirs)) { header('HTTP/1.1 403 Forbidden'); exit; } $allowedExts = array('jpg', 'jpeg', 'png', 'gif'); $files = scandir($targetDir); $images = array(); foreach ($files as $file) { $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); if (in_array($ext, $allowedExts) && !is_dir($targetDir . '/' . $file)) { $images[] = '/' . $targetDir . '/' . $file; } } header('Content-Type: application/json'); echo json_encode($images); ?>
修改JS组件的AJAX请求逻辑:
// 替换原$.ajax部分 $.ajax({ url: 'get-images.php?dir=' + src, dataType: 'json', success: function(images) { // 生成标题卡片逻辑不变... // 循环图片列表生成卡片 images.forEach(function(imgUrl) { var card = ` <div class='card clickable'> <a data-fancybox='gallery' href='`+ imgUrl + `'> <img class='card-img-top' src='`+ imgUrl + `'/> </a> </div> `; $("#gallery").append(card); }); } });
4. 确认路径正确性
确保组件src属性使用的是网站根目录相对路径,比如/images/asphalt而非images/asphalt,避免因服务器环境差异导致路径解析错误。
内容的提问来源于stack exchange,提问作者Cameron Nelson
相关产品推荐
相关产品推荐

