如何防止 iis 默认未找到页面并显示自定义 reactjs 未找到页面
how to prevent iis default not-found page and show a custom reactjs not-found page
所以我有一个部署在 IIS 上的 React 应用程序,我正在使用 React 路由器和我的路由,它们的顺序没问题,在开发模式下本地一切正常,
我的routes.js文件returns这样的路线:
<Router history={history}>
<Switch>
{/* there are some other routes that are removed from here */}
{/* token is the jwt token for user */}
{!token && <Route path="/Home" component={HomePage} />}
<Route path="/" exact>
{!!token ? <Redirect to="/Dashboard" /> : <Redirect to="/Home" />}
</Route>
<Route path="*" exact component={FourOFour} />
</Switch>
</Router>
我的“未找到页面”有一个 jsx 文件,returns 组件 FourOFour,
如我所说,包括未找到页面在内的所有内容在我的机器上的开发模式下都显示完全正常。但是当我在 IIS 上部署我的 React 应用程序时,我的自定义未找到页面不会显示,而是显示 IIS 的默认 404 页面,如何让 ISS 停止干扰我的路由?
PS:我知道处理 404 等错误是服务器的工作,这是默认行为,我也尝试了一些我在网上找到的建议,但其中一些正在毁掉一切都不清楚发生了什么,
所以我希望能清楚地解释 IIS 配置的步骤,
任何建议表示赞赏
更新
我走过的路
首先,我在客户端的路由器中处理了错误 404,它没有工作,因为 iis 有默认的 html 常见错误页面,例如 404、500,...它有点捕获错误在请求到达客户端之前,所以我发现这是服务器而不是客户端处理的问题,然后我在 iis 中尝试了不同的配置,因为 iis 对每个站点都有一个“错误页面”部分,在这个部分你可以改变它处理此类错误的方式,对于每种类型的错误(实际上是每个状态代码)它有三个选项:
- 将静态文件中的内容插入到错误响应中
你可以给一个静态 html 页面的路径,它会显示出来,但正如我上面所说,我找不到的页面是写在一个 jsx 文件中的,它有一个 loooooot java-脚本代码,将所有内容都放在 html 页面中并使用这种方式并非不可能,但它会使我的代码变脏,我更喜欢一种不会让我的代码变得混乱的方式,另外我尝试这种方式只是为了看看它是否有效但它显示此错误:
“您要查找的资源已被删除、更名或暂时不可用。”
- 在此站点执行一个url
这对我来说可能是最好的解决方案,我可以在我的路线中设置一个“/404”路径,重定向到我未找到的页面,一切看起来都很干净,但遗憾的是它没有用,看起来 iis 没有重定向到我的特定 url,而是显示了一个白屏,这比默认的 404 页面更糟糕...
- 响应 302 重定向
这不是我的解决方案,因为我不想重定向到我的应用程序之外的页面
我也仔细阅读了,但仍然不知道该怎么做
先制作NotFound页面和Route代码
<Route path="/notfound" component={NotFound} />
如果主组件渲染出错,再输入一些重定向代码。(主组件只是一个例子)
export const Main = () => {
const history = useHistory();
useEffect(() => {
if (error) {
history.push("/notfound")
}
})
render ....
}
希望你能找到解决办法!
顺便说一句,React-Router 现在是 v6 你应该知道了:)
既然你提到在本地开发模式下一切正常,IIS 中的设置可能有问题。以下步骤值得尝试:(1) 打开 IIS 管理器 (2) 识别您正在使用的应用程序 (3) 在主页面板中打开“错误页面” (4) 使用添加(如果您没有 404状态代码)或编辑(如果您已经有 404 状态代码)在操作窗格 (5) 在“状态代码”(6) 下输入 404 作为响应操作,select“执行 URL在此站点上”并为自定义错误页面输入 URL。注意:请确保您使用的是相对路径。
此外,IIS 的版本可能会导致一些实践上的差异。如果您还有任何问题,请随时与我们联系,更多详细信息可以帮助我们更好地解决您的问题。
这就是您的 web.config
的样子,见下文。
关键部分是名为 ReactRouter Routes
的 rewrite rule,它实质上将路由委托给反应路由器,即通过“指向”index.html 的客户端路由,因此反应路由器可以接管.
您会注意到一个 <match url=".*">
与请求 URL 的模式匹配,使用带有模式的 reg ex。* 所以浏览器发送的所有 url 都被捕获并抛给客户端所以说话。
确保在 IIS 上安装了 URL Rewrite。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReactRouter Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
因为我在答案中找不到可行的解决方案,所以我这样做了:
首先我在ErrorPages > 404 > Edit Custom Error Page
菜单中选择了第二个选项,即execute a URL on this site
:
我给了它 /
值,它是我的 react-app 根目录的相对路径。
这样,每当发生错误时,iis 都会调用 react-app 并将控制权交给它,例如,如果 Dashboard
的路径是 /dashboard,并且用户输入错误并且有 /dahboard(中间缺少 s)或任何其他问题,not found
组件将被渲染,有趣的是浏览器中的 URL 将保持不变(例如 /dahboard)并获胜'改为/
所以我有一个部署在 IIS 上的 React 应用程序,我正在使用 React 路由器和我的路由,它们的顺序没问题,在开发模式下本地一切正常,
我的routes.js文件returns这样的路线:
<Router history={history}>
<Switch>
{/* there are some other routes that are removed from here */}
{/* token is the jwt token for user */}
{!token && <Route path="/Home" component={HomePage} />}
<Route path="/" exact>
{!!token ? <Redirect to="/Dashboard" /> : <Redirect to="/Home" />}
</Route>
<Route path="*" exact component={FourOFour} />
</Switch>
</Router>
我的“未找到页面”有一个 jsx 文件,returns 组件 FourOFour,
如我所说,包括未找到页面在内的所有内容在我的机器上的开发模式下都显示完全正常。但是当我在 IIS 上部署我的 React 应用程序时,我的自定义未找到页面不会显示,而是显示 IIS 的默认 404 页面,如何让 ISS 停止干扰我的路由?
PS:我知道处理 404 等错误是服务器的工作,这是默认行为,我也尝试了一些我在网上找到的建议,但其中一些正在毁掉一切都不清楚发生了什么,
所以我希望能清楚地解释 IIS 配置的步骤, 任何建议表示赞赏
更新
我走过的路
首先,我在客户端的路由器中处理了错误 404,它没有工作,因为 iis 有默认的 html 常见错误页面,例如 404、500,...它有点捕获错误在请求到达客户端之前,所以我发现这是服务器而不是客户端处理的问题,然后我在 iis 中尝试了不同的配置,因为 iis 对每个站点都有一个“错误页面”部分,在这个部分你可以改变它处理此类错误的方式,对于每种类型的错误(实际上是每个状态代码)它有三个选项:
- 将静态文件中的内容插入到错误响应中
你可以给一个静态 html 页面的路径,它会显示出来,但正如我上面所说,我找不到的页面是写在一个 jsx 文件中的,它有一个 loooooot java-脚本代码,将所有内容都放在 html 页面中并使用这种方式并非不可能,但它会使我的代码变脏,我更喜欢一种不会让我的代码变得混乱的方式,另外我尝试这种方式只是为了看看它是否有效但它显示此错误: “您要查找的资源已被删除、更名或暂时不可用。”
- 在此站点执行一个url
这对我来说可能是最好的解决方案,我可以在我的路线中设置一个“/404”路径,重定向到我未找到的页面,一切看起来都很干净,但遗憾的是它没有用,看起来 iis 没有重定向到我的特定 url,而是显示了一个白屏,这比默认的 404 页面更糟糕...
- 响应 302 重定向
这不是我的解决方案,因为我不想重定向到我的应用程序之外的页面
我也仔细阅读了
先制作NotFound页面和Route代码
<Route path="/notfound" component={NotFound} />
如果主组件渲染出错,再输入一些重定向代码。(主组件只是一个例子)
export const Main = () => {
const history = useHistory();
useEffect(() => {
if (error) {
history.push("/notfound")
}
})
render ....
}
希望你能找到解决办法!
顺便说一句,React-Router 现在是 v6 你应该知道了:)
既然你提到在本地开发模式下一切正常,IIS 中的设置可能有问题。以下步骤值得尝试:(1) 打开 IIS 管理器 (2) 识别您正在使用的应用程序 (3) 在主页面板中打开“错误页面” (4) 使用添加(如果您没有 404状态代码)或编辑(如果您已经有 404 状态代码)在操作窗格 (5) 在“状态代码”(6) 下输入 404 作为响应操作,select“执行 URL在此站点上”并为自定义错误页面输入 URL。注意:请确保您使用的是相对路径。 此外,IIS 的版本可能会导致一些实践上的差异。如果您还有任何问题,请随时与我们联系,更多详细信息可以帮助我们更好地解决您的问题。
这就是您的 web.config
的样子,见下文。
关键部分是名为 ReactRouter Routes
的 rewrite rule,它实质上将路由委托给反应路由器,即通过“指向”index.html 的客户端路由,因此反应路由器可以接管.
您会注意到一个 <match url=".*">
与请求 URL 的模式匹配,使用带有模式的 reg ex。* 所以浏览器发送的所有 url 都被捕获并抛给客户端所以说话。
确保在 IIS 上安装了 URL Rewrite。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReactRouter Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
因为我在答案中找不到可行的解决方案,所以我这样做了:
首先我在ErrorPages > 404 > Edit Custom Error Page
菜单中选择了第二个选项,即execute a URL on this site
:
我给了它 /
值,它是我的 react-app 根目录的相对路径。
这样,每当发生错误时,iis 都会调用 react-app 并将控制权交给它,例如,如果 Dashboard
的路径是 /dashboard,并且用户输入错误并且有 /dahboard(中间缺少 s)或任何其他问题,not found
组件将被渲染,有趣的是浏览器中的 URL 将保持不变(例如 /dahboard)并获胜'改为/