我有一个在 IIS 7.5 下运行的 php 网站。该站点受 Windows 身份验证保护,并且运行良好:

当用户访问该站点时,他们会被要求输入用户名/密码,并在通过身份验证后通过。如果用户单击取消或错误输入密码 3 次,则会显示 401 错误页面:

现在我想展示解释如何登录的自定义页面。所以我转到错误页面,选择状态代码 401.2 并将其指向我想要显示的页面:

然后确保为每个人打开自定义错误。和 kaa-boom!身份验证不再起作用,用户不会看到密码提示。正如文档所说,Windows 身份验证的工作原理是首先发送 401 回复,然后浏览器要求用户提供凭据,然后他们确定下一步要做什么。
这里发生了什么:在第一次请求页面时,IIS 尝试发送 401 标头,但注意到 web.config 显示“在 401 上重定向到此页面”。而不是身份验证,它只提供重定向页面。
我试过更换 401、401.1、401.2 - 没有区别。
我做错了什么以及如何在用户身份验证错误时提供自定义页面?
ps 这是 web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="500" subStatusCode="-1" />
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="401" subStatusCode="-1" />
<error statusCode="401" subStatusCode="2" prefixLanguageFilePath="" path="/not_restricted/401.htm" responseMode="ExecuteURL" />
<error statusCode="404" prefixLanguageFilePath="" path="/not_restricted/404.htm" responseMode="ExecuteURL" />
</httpErrors>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
</system.webServer>
<system.web>
<identity …Run Code Online (Sandbox Code Playgroud) 我正在尝试为 nginx 中的非 HTTPS 请求返回自定义 400 错误页面。我是 nginx 的新手,但我在自定义错误页面上阅读了许多示例页面,但似乎对我没有任何作用。我的配置:
server {
listen 80;
error_page 400 /400.html;
location = /400.html {
root /var/www/html;
}
return 400;
}
Run Code Online (Sandbox Code Playgroud)
在返回工作,因为如果我改变代码(如401或500),我得到了适当的默认nginx的错误页面。我知道该文件存在,因为如果我取出退货,它将直接为我的 400.html 页面提供服务,没有任何问题。但是当我返回错误代码时,我尝试过的任何事情都没有导致我的自定义页面出现。
我错过了什么?
更新:我尝试过的其他变体无济于事:
server {
listen 80;
error_page 400 /400.html;
location = /400.html {
root /var/www/html;
}
return 400;
}
server {
listen 80;
root /var/www/html;
error_page 400 /400.html;
location = /400.html {
allow all;
}
return 400;
}
server {
listen 80;
root /var/www/html;
error_page 400 …Run Code Online (Sandbox Code Playgroud) 首先:简单的端口 80 -> 端口 443 重写不会解决这个问题。在几乎所有以前的问题,邮件线程,论坛线程等中,我发现这是第一个无知的回复,并且被重复了好几次。
其次:是的,我知道您不能在同一端口上提供 HTTP 和 HTTPS 流量。 这不是那个。
通过端口倍增托管多个站点的 Apache 服务器。端口 80 服务于公共站点。端口 443 服务于该站点的安全版本。
端口 7443、8443 和 9443 分别为单独的 SSL 安全站点提供服务。
如果用户输入错误的 URL,或者给出的链接无效,比如http://hostname.tld:7443,他们会看到以下荒谬的页面:

而不是服务器只是将它们重定向到https://hostname.tld:7443。
我的问题是,以Zeus 的屁眼的名义,您如何修改 Apache 的行为或此错误消息以自动重定向用户?
Apache 显然是在为非 https 请求提供服务(以显示该错误消息),即使它是为 HTTPS 配置的。对我来说,不只是默认进行重定向似乎非常愚蠢,但我可以理解为什么他们会采用他们所做的行为,即使我不同意。所以我的问题是:你能改变它吗?他们正在某处处理错误,并且 Apache 是配置的聚宝盆,因此有理由在某处处理此行为的指令,但到目前为止,我一直无法在几个小时的修补中找到它。
我尝试了多种方法,包括:
使用ErrorDocument 400指令获取 CGI 和仅发送Status 301和Location标头的 PHP 脚本。这导致空白页。ErrorDocument 400 https://hostname.tld:7443简单地使用会导致该链接显示在页面上。
使用mod_rewriteI 或 Google 能想到的几乎所有组合,包括完全指导网站的一揽子声明;这些永远不会奏效。从字面上看,他们什么都不做。我猜测 Apache 甚至在尝试处理重写指令之前就遇到了上述错误。 …
以下是 Nginx 服务器配置示例。如果没有“魔法护身符”位置块,代理的错误内容会导致 Nginx 404 页面,而不是提供自定义的错误页面。
删除 proxy_intercept_errors 指令会提供带有正确 http 错误代码标头的正确代理错误页面。
无论魔法护身符是否存在,非代理错误页面都会正确呈现。
关于究竟发生了什么的任何想法?
server {
server_name mydomain.com "";
listen 80;
root /var/www;
error_page 400 401 402 403 404 500 501 502 503 504 /admin/error_page.htm;
proxy_intercept_errors on;
location /proxy/ {
proxy_read_timeout 60s;
proxy_set_header Host $host;
proxy_pass http://myservers;
}
location /test404/ {
return 404;
}
location /admin/ { # this line constitute a magical talisman that fixes proxied error interception(???)(!)
rewrite ^(/admin)(.*)$ /admin$2 break;
}
}
Run Code Online (Sandbox Code Playgroud) 在我的 Windows Server 2008 r2 上的 IIS 7 (.5) 中,错误页面有两个位置:“功能视图”中“ASP.NET”下的“.NET 错误页面”和“IIS”下的“错误页面”看法。
似乎第一个没有做任何事情,但后者做了(在我的 Web 应用程序中)。
为什么有两个,有什么区别?
这是我的 nginx 配置的一个片段:
server {
error_page 500 /errors/500.html;
}
Run Code Online (Sandbox Code Playgroud)
当我在我的应用程序中导致 500 时,Chrome 只显示其默认的 500 页面(Firefox 和 Safari 显示空白页面)而不是我的自定义错误页面。
我知道该文件存在,因为我可以访问http://server/errors/500.html并看到该页面。我还可以将文件移动到文档根目录并将配置更改为:
server {
error_page 500 /500.html;
}
Run Code Online (Sandbox Code Playgroud)
并且 nginx 正确地提供页面,所以它似乎不是服务器上配置错误的其他东西。
我也试过:
server {
error_page 500 $document_root/errors/500.html;
}
Run Code Online (Sandbox Code Playgroud)
和:
server {
error_page 500 http://$http_host/errors/500.html;
}
Run Code Online (Sandbox Code Playgroud)
和:
server {
error_page 500 /500.html;
location = /500.html {
root /path/to/errors/;
}
}
Run Code Online (Sandbox Code Playgroud)
没有运气。
这是预期的行为吗?错误页面是否必须存在于文档根目录中,或者我是否遗漏了一些明显的内容?
更新 1:这也失败了:
server {
error_page 500 /foo.html;
}
Run Code Online (Sandbox Code Playgroud)
何时foo.html确实存在于文档根目录中。似乎其他东西正在覆盖我的配置,但此块是唯一/etc/nginx/*引用该error_page指令的地方。
还有其他地方可以设置nginx配置吗?
尽管 Ansible 本身有触发自定义错误的方法,但我找不到类似 Jinja 的任何内容。
我当前的方法使用语法错误:
{% if 'ansible_mounts' in hostvars[host] %}
# {{ host }} knows its mount-points
{% else %}
# {% error!! No ansible_mounts listed for host - fact-gathering must've failed %}
{% endif %}
Run Code Online (Sandbox Code Playgroud)
但是那些在运行时渲染得很差——需要查看模板文件内部并搜索错误(渲染甚至不包括行号!)。
有没有办法从 Jinja 模板内部输出整洁的失败消息?
我正在运行带有 2 个自定义 servlet 的 Apache Tomcat 服务器。树结构看起来像:
$CATALINA_HOME/webapps/
ROOT/
WEB-INF/
servlet1/
META-INF/
WEB-INF/
servlet2/
META-INF/
WEB-INF/
Run Code Online (Sandbox Code Playgroud)
我正在尝试为每个 servlet 添加一个自定义错误 html 页面,该页面将显示在错误 400、404 上以及当 servlet 出现异常时(例如应该在 http 请求中发送给 servlet 的信息是不在那里)
我添加到 $CATALINA_HOME/webapps/servlet1/WEB-INF/web.xml
<error-page>
<error-code>400</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.html</location>
</error-page>
Run Code Online (Sandbox Code Playgroud)
我error.html在$CATALINA_HOME/webapps/ROOT/. 这似乎不起作用。当我输入“www.server.com/servlet1/SomRandomStuff以获取 404 时,会显示一个空白页面,而不是 error.html。当我调用 servlet 而不将正确的信息传递给它时,还会发生其他事情,浏览器会询问我是否要下载文件。
我我试过error.html不放在ROOT而是放在 servlet1 目录上。没有工作。我检查了error.html具有正确的权限,没关系。我没有想法,我在网上找到的几个教程非常模糊。
我究竟做错了什么?我如何实现这一点 - 为每个 servlet 显示一个自定义错误页面?
感谢您的帮助。
有什么方法可以防止 IIS 自动覆盖返回 500 或 400 范围内的状态代码的 Web 应用程序的输出?
举个例子,在 ColdFusion 中,我可以创建以下页面:
<cfheader statuscode="500" statustext="Error">
Sorry, an error occurred.
Run Code Online (Sandbox Code Playgroud)
行为应该是我看到一个页面,上面写着“对不起,发生了错误”。并在标题中看到状态代码为 500。
相反,我看到:
Server Error
500 - Internal server error.
There is a problem with the resource you are looking for, and it cannot be displayed.
Run Code Online (Sandbox Code Playgroud)
在可爱的 IIS 样式中。
我尝试删除 500 个自定义状态页面,但这只是导致:
The page cannot be displayed because an internal server error has occurred.
Run Code Online (Sandbox Code Playgroud)
没有任何可爱的造型。
看起来这种情况发生在任何返回不在 200 或 300 范围内的代码的页面上。
我有一个反向代理 Apache,它将请求移动到 Tomcat servlet。Apache中虚拟主机上的配置是:
<VirtualHost 10.10.10.10:80>
ProxyPass /Site1/ServLet1 http://1.1.1.1/Site1/ServLet1
ProxyPassReverse /Site1/ServLet1 http://1.1.1.1//Site1/ServLet1
ProxyPass /Site2/ServLet2 http://2.2.2.2/Site2/ServLet2
ProxyPassReverse /Site2/ServLet2 http://2.2.2.2/Site1/ServLet1
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)
本质上,如果涉及到10.10.10.10和 requests ,则将其/Site1/ServLet1路由到/Site1/ServLet1.
如果我添加
<VirtualHost 10.10.10.10:80>
ProxyPass /Site1/ServLet1 http://1.1.1.1/Site1/ServLet1
ProxyPassReverse /Site1/ServLet1 http://1.1.1.1//Site1/ServLet1
ErrorDocument 404 /customerrors/site1/404.html
ProxyPass /Site2/ServLet2 http://2.2.2.2/Site2/ServLet2
ProxyPassReverse /Site2/ServLet2 http://2.2.2.2/Site1/ServLet1
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)
所以它会显示一个自定义错误site1(我设置了 ErrorDocument),它将被提供给两者。
如何在每个站点维护这种配置的情况下拥有不同的 404 错误页面?
谢谢
编辑:
如果我根据以下评论修改配置,例如:
<Location /Site1/ServLet1/>
ProxyPass http://1.1.1.1/Site1/ServLet1
ProxyPassReverse http://1.1.1.1/Site1/ServLet1
ErrorDocument 404 /customerrors/site1/404.html
</Location>
Run Code Online (Sandbox Code Playgroud)
然后我仍然可以到达http://1.1.1.1/Site1/ServLet1但没有显示任何错误页面
custom-errors ×10
nginx ×3
apache-2.2 ×2
iis-7.5 ×2
ansible ×1
http ×1
https ×1
iis ×1
jinja ×1
proxy ×1
template ×1
tomcat ×1
virtualhost ×1