How can I configure IIS to serve directories without trailing slashes and always serve relative to root path?

北慕城南 提交于 2019-12-12 04:39:55

问题


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

回答1:


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.



来源:https://stackoverflow.com/questions/47274704/how-can-i-configure-iis-to-serve-directories-without-trailing-slashes-and-always

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!