共享主机上的 html 站点出现 500 错误,我的 .htaccess 语法是否有误?

500 error for html site on shared hosting, is my .htaccess syntax wrong?

第一次来。我实际上是一名来自墨西哥的 工业和系统工程师,正在努力成为一名自学成才的 Web Developer/Graphic 设计师我很抱歉 如果我的英语有问题并且是个菜鸟,尤其是如果我的问题已经被其他人问过,或者其他什么。 (虽然我确实搜索了问题)

我刚刚完成(使用购买的 html 模板)一家新公司(我的客户)网站的第 1 阶段(以及一切设计明智的):https://www.starhauss.com/

网站运行良好...考虑到我的要求,考虑到它是 1º 阶段,它有一些小缺陷...我认为。

无论如何...

我需要用 .htaccess 为我的客户做(并尝试)几件事,ASAP:

  1. 重定向到自定义 404
  2. 声明西班牙语(该站点将很快在 /en/ 目录中有英文版本)
  3. 阻止合理的服务器信息
  4. 禁用目录列表
  5. 从网址中删除 www
  6. 从 url 中删除 html 文件扩展名
  7. 阻止隐藏文件出现
  8. 阻止“有风险”的文件出现
  9. 在 url 上强制使用 https
  10. 检查并更正网址上的简单拼写错误

我从不同的来源研究了 Apache 指南和所有内容,并且我想出了自己的 .htaccess 文件,但是我'我不确定语法是否错误,或者我是否需要联系相应的 托管支持人员 以便他们允许执行我的文件,因为当它上传时(RIGHT现在它没有上传 ) 和 Cyber​​Duck 到根目录编码文本通过 US-ASCII755 文件权限,访问我的站点会导致 500 内部服务器错误。我不知道共享托管公司的服务器上默认启用了哪些模块,但据我了解,它们确实适用于 Apache 平台

我的.htaccess代码是下一个

# redirect not found
ErrorDocument 404 /404.html

# declare language for multilingual sites, adding a .htaccess file for each language subdirectory
DefaultLanguage es

# prevent server from outputing sensible information
ServerSignature Off

# disable directory listings, only when on
Options -Indexes

# requirement to change urls & such
RewriteEngine On

# use in subdirectories if rewrite rules are not working properly
# RewriteBase /

# mod_rewrite.c wrapper works mainly with WordPress & such
# <IfModule mod_rewrite.c>

# remove www from urls
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

# remove html file extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ .html [NC, L]

# block hidden files
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\." - [F]

# </IfModule>

# block risky files
<FilesMatch "(^#.*#|\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|sw[op])|~)$">
  Order allow,deny
  Deny from all
  Satisfy All
</FilesMatch>

# force https
<IfModule mod_headers.c>
  Header set Strict-Transport-Security max-age=16070400;
</IfModule>

# check & correct url spelling errors, useful for SEO
<IfModule mod_speling.c>
  CheckSeplling On
</IfModule>

那么,小伙伴们,你们怎么看?它应该工作吗?代码语法、顺序或其他什么有问题吗?文件工作的服务器端是否缺少某些东西?如果是这样,如果我无法访问 Httpd.Conf,我怎么知道?我应该联系共享主机支持以允许我的文件吗?

RewriteRule ^([^\.]+)$ .html [NC, L]

您在 RewriteRule flags 参数中有一个错误的 space。这将导致 500 内部服务器错误,如果您查看服务器的 error.log,您将看到报告的错误,如“RewriteRule:错误的标志分隔符”。

每当您收到 500 错误(这只是一般的服务器响应)时,您需要检查服务器的错误日志以了解该错误的详细信息。

在这种情况下,[NC, L] 应该是 [NC,L]。虽然NC标志在这里是多余的,所以[L]就足够了。

<IfModule mod_speling.c>
  CheckSeplling On
</IfModule>

你拼写 CheckSpelling 错了。 (这也会触发 500 错误响应。)

  1. Force https on the urls

     # remove www from urls
     RewriteCond %{HTTPS} !=on
     RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
     RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
    

您实际上并没有在任何地方“强制使用 HTTPS”。

以上仅删除 HTTP 上的 www。上面的www to non-www redirect 和redirecting to HTTP, not HTTPS 为什么要特意检查请求是not HTTPS?

您可以将上面的内容更改为以下内容以删除 HTTP 和 HTTPS 上的 www(同时规范化 HTTPS):

  # Remove www (redirect to HTTPS)
  RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
  RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]

并添加一个额外的规则来强制使用 HTTPS(但是,请参阅下面关于 HSTS*1 的注释):

  # Force HTTPS
  RewriteCond %{HTTPS} !=on
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# force https
<IfModule mod_headers.c>
  Header set Strict-Transport-Security max-age=16070400;
</IfModule>

这并不是严格意义上的“强制 https”。

此“HSTS header”指示浏览器在用户通过 HTTPS 访问网站后始终 请求 HTTPS。如果用户仅通过 HTTP 访问该站点,它什么也不做(因此要求首先 redirect/force 用户访问 HTTPS - 见上文)。但是,这还不完整 - 您需要先在 同一主机 上重定向(*1ie . 反转上面的两个重定向)并且还在通过 HTTPS 删除 www 的 301 重定向上设置 header(这个指令没有)。理想情况下,您应该避免通过纯 HTTP 发送 header(尽管这并不重要,因为浏览器会简单地忽略它)。

我会避免一开始就设置 HSTS,直到您的站点通过 HTTPS 正常工作。您应该将 HSTS 视为一次 one-way 旅行,对此进行回溯是有问题的(对于通过 HTTPS 访问的 任何人 max-age=16070400 将持续 6 个月以上) .

请参阅 CodeReview 堆栈中有关 HSTS 实施的以下相关问题:https://codereview.stackexchange.com/questions/250805/hsts-recommendations-in-htaccess

  Order allow,deny
  Deny from all
  Satisfy All

这些是 Apache 2.2 指令,以前在 Apache 2.4 上已弃用。我假设您使用的是 Apache 2.4(Apache 2.2 在将近 2 年前停产了)。您应该改用 Apache 2.4 指令:

Require all denied