如何配置 IIS 以在没有尾部斜杠的情况下提供目录并始终相对于根路径提供服务? [英] How can I configure IIS to serve directories without trailing slashes and always serve relative to root path?

查看:33
本文介绍了如何配置 IIS 以在没有尾部斜杠的情况下提供目录并始终相对于根路径提供服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 IIS 中托管了一个单页应用程序,我想确保所有请求都被定向到/index.html(它将解释 url 并处理所有路由客户端).此规则的唯一例外是当请求是针对磁盘上的实际文件时,例如 *.js、*.css、*.png 等(毕竟我仍然需要能够加载应用程序;-).使用以下 web.config 文件几乎一切正常:

<预><代码><配置><system.webServer><httpErrors errorMode="Custom" existingResponse="Replace"><remove statusCode="404"/><error statusCode="404" responseMode="ExecuteURL" path="/index.html"/></httpErrors></system.webServer></配置>

如果我请求 mydomain.com/contact,/index.html 页面会按预期提供,但是如果我请求 mydomain.com/contact/(注意附加的尾部斜杠),那么我的应用程序中的所有相对路径都会爆炸,因为浏览器尝试加载/contact/some-file.js 而不是/some-file.js.我可以通过让我的所有路径都扎根来解决这个问题,但出于更多的原因,不仅仅是惯性,我希望能够坚持使用相对路径.

当磁盘上存在与请求的 url 匹配的目录时,会出现第二个相关问题.例如,如果我请求/services 并且磁盘上有一个/services 目录,那么请求会自动更改为/services/(我认为 IIS 是这里的罪魁祸首),然后会产生 403 错误响应,因为 IIS 理所当然地拒绝提供服务目录内容.

请注意,将其添加到 web.config 部分解决了第二个问题:

<error statusCode="403" responseMode="ExecuteURL" path="/index.html"/>

部分原因是它导致 403 失败,无法使用/index.html 作为其响应,但其余资源是相对于/services/而不是/加载的(这又回到了上面相对路径的第一个问题).这也是部分原因,因为对/services 的请求仍在更改为/services/.

所以我的问题是,当磁盘上有匹配的目录时,如何防止/services 之类的路径更改为/services/以及如何使所有重定向服务于来自根的响应并将所有路径路由到客户端(即将对/contact/的请求视为对/contact 的请求)?

更新:这似乎准确地描述了问题:https://support.microsoft.com/en-us/help/298408/iis-generates-courtesy-redirect-when-folder-without-trailing-slash-is

我使用的是 IIS 10,但行为是相同的.

403 状态代码用于禁止",因为目录列表被正确拒绝,因此将其添加到 web.config 是在治疗症状而不是原因.我测试将 301 和 302 添加到 web.config 并且 IIS 不允许这样做并产生错误:

'statusCode' 属性无效.整数值必须介于 400 和 999 之间(包括 400 和 999)

解决方案

据:

https://forums.iis.net/t/1153462.aspx?Is+it+possible+to+disable+the+courtesy+301+redirect+for+URL+requests+that+lack+a+trailing+slash+

没有内置的方法来改变 IIS 中的 301 行为,使用 url 重写是处理这个问题的唯一方法.所以我安装了 IIS URL 重写模块 (https://www.microsoft.com/en-us/download/details.aspx?id=47337) 并将其添加到 web.config 中:

 <规则><规则名称="删除尾部斜杠" stopProcessing="true"><match url="(.*)/$"/><条件><add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/><add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/></条件><action type="Redirect" redirectType="Permanent" url="{R:1}"/></规则></规则></rewrite>

现在所有带有斜杠的请求都将其删除,IIS 不再执行 301 重定向以重新添加斜杠,客户端加载资源是相对于根加载的(由于没有尾部斜杠),并且客户端路由接管并加载正确的内容.

I have a single page app hosted in IIS and I want make sure all requests are directed to /index.html (which will interpret the url and handle all routing client side). The only exception to this rule is when the request is for an actual file that is on disk such as *.js, *.css, *.png, etc. (I still need to be able to load the app after all ;-). Nearly everything works correctly with the following web.config file:

<configuration>
    <system.webServer>
        <httpErrors errorMode="Custom" existingResponse="Replace">
            <remove statusCode="404"/>
            <error statusCode="404" responseMode="ExecuteURL" path="/index.html" />
        </httpErrors>
    </system.webServer>
</configuration>

If I request mydomain.com/contact the /index.html page is served as expected, but if I request mydomain.com/contact/ (note the additional trailing slash) then all the relative paths in my app blow up because the browser tries to load /contact/some-file.js instead of /some-file.js. I can fix this by making all my paths rooted, but for more reasons than just inertia I want to be able to stick with relative paths.

The second related issue occurs when there is a directory on disk matching the requested url. For example, if I request /services and there is a /services directory on disk then the request is automatically changed to /services/ (I think IIS is the culprit here) which then produces a 403 error response because IIS rightfully refuses to serve up the directory contents.

Note that adding this to web.config partially solves the second problem:

<remove statusCode="403"/>
<error statusCode="403" responseMode="ExecuteURL" path="/index.html" />

Partially because it causes the 403 failure to use /index.html for its response but the rest of the resources are loaded relative to /services/ instead of / (which is back to the first issue with relative paths above). Also it is partial because a request to /services is still getting changed to /services/.

So my question is how can I prevent paths like /services from being changed to /services/ when there is a matching directory on disk and how can I make all redirects serve the response from the root and leave all path routing to the client (that is to treat a request for /contact/ as if it were a request for /contact)?

Update: This seems to describe the problem accurately: https://support.microsoft.com/en-us/help/298408/iis-generates-courtesy-redirect-when-folder-without-trailing-slash-is

I am using IIS 10 but the behavior is the same.

The 403 status code is for 'Forbidden' because the directory listing is correctly denied so adding this to web.config is treating the symptom and not the cause. I tested adding 301 and 302 to web.config and IIS does not allow this and produces the error:

The 'statusCode' attribute is invalid. Integer value must be between 400 and 999 inclusive

解决方案

According to:

https://forums.iis.net/t/1153462.aspx?Is+it+possible+to+disable+the+courtesy+301+redirect+for+URL+requests+that+lack+a+trailing+slash+

there is no built in way to change the 301 behavior in IIS, and using url rewriting is the only way to deal with this. So I installed the IIS URL Rewrite Module (https://www.microsoft.com/en-us/download/details.aspx?id=47337) and added this to web.config instead:

    <rewrite>
        <rules>
            <rule name="Remove trailing slash" stopProcessing="true">
                <match url="(.*)/$" />
                <conditions>
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                </conditions>
                <action type="Redirect" redirectType="Permanent" url="{R:1}" />
            </rule>
        </rules>
    </rewrite>

Now all requests with a trailing slash get it removed, IIS no longer performs 301 redirects to add back the slash, the client side loads resources are loaded relative to the root (thanks to no trailing slash), and the client side routing takes over and loads the correct content.

这篇关于如何配置 IIS 以在没有尾部斜杠的情况下提供目录并始终相对于根路径提供服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆