开发者

IIS: 405 (Method not allowed) when posting to default page

开发者 https://www.devze.com 2023-01-04 14:58 出处:网络
i want to POST form data to the default page of a web-server, e.g.: POST http://errorreporting.e开发者_如何学Goxample.com/ HTTP/1.1

i want to POST form data to the default page of a web-server, e.g.:

POST http://errorreporting.e开发者_如何学Goxample.com/ HTTP/1.1

i want the server to be responsible for 302 redirecting the client to where the POST should go. The default.asp file on the server performs this task (which is the technique Microsoft recommends), by performing the Redirect:

default.asp:

<%
   Response.Redirect "SubmitError.ashx"
%>

When i simply browse the server:

GET http://errorreporting.example.com/ HTTP/1.1

i get the expected response from the server:

HTTP/1.1 302 Object moved
Server: Microsoft-IIS/5.0
Location: SubmitError.ashx
...

But when i POST to the server:

POST http://errorreporting.example.com/ HTTP/1.1

The server gets very grumpy with me:

HTTP/1.1 405 Method not allowed
Connection: close
Allow: OPTIONS, TRACE, GET, HEAD
...

i want the server to be able to redirect the client to the appropriate submit URL, rather than hard-coding the client with the URL. This is, of course, because the URL could (i.e. has) changed:

  • http://errorreporting.example.com/SubmitError.asp
  • http://errorreporting.example.com/SubmitError.aspx
  • http://errorreporting.example.com/SubmitError.ashx
  • http://errorreporting.example.com/ErrorReporting/Submit.ashx
  • http://errorreporting.example.com/submiterror.php
  • http://errorreporting.example.com/submit/submiterror.ashx

etc.

Note: If i change the URL to include the document location:

/* SErrorReportingUrl = 'http://www.example.com:8088/ErrorReporting/SubmitError.ashx';
   SErrorReportingUrl = 'http://www.example.com/ErrorReporting/SubmitError.ashx';
   SErrorReportingUrl = 'http://errorreporting.example.com:8088/ErrorReporting/SubmitError.ashx';
   SErrorReportingUrl = 'http://errorreporting.example.com/SubmitError.ashx';
   SErrorReportingUrl = 'http://errorreporting.example.com';
   SErrorReportingUrl = 'http://errorreporting.example.com/SubmitError.ashx'; 
*/
   SErrorReportingUrl = 'http://errorreporting.example.com/submit/SubmitError.ashx';

It works fine:

HTTP/1.1 200 OK


Turns out getting IIS to support POST doesn't really help.

i'm using XMLHttpRequest to perform the POSTs. Nearly every implementation of XMLHttpRequest out there (e.g. Chrome, Internet Explorer, MSXML) has a bug where it performs a GET, instead of a POST, after following the redirect.

The W3C's XMLHttpReqest specification says that redirects should be followed and requests reissued:

If the response is an HTTP redirect:

If the redirect does not violate security (it is same origin for instance), infinite loop precautions, and the scheme is supported, transparently follow the redirect while observing the same-origin request event rules.

Note: HTTP places requirements on the user agent regarding the preservation of the request method and request entity body during redirects, and also requires end users to be notified of certain kinds of automatic redirections.

And here's a site where you can test the bug in your browser's XmlHttpRequest implementation.


In the end, i'll work around an IIS bug, and an XMLHttpRequest bug, by having my "default" page do everything that a 302 redirect would, but return 200 OK instead:

HTTP/1.1200 OK
Connection: close
Date: Sun, 27 Jun 2010 13:28:14 GMT
Server: Microsoft-IIS/6.0
Location: http://errorreporting.example.com/submit/SubmitError.ashx
Content-Length: 92
Content-Type: text/html
Cache-control: private

<HTML><BODY>This content has moved <A href="submit/SubmitError.ashx">here.</A></BODY></HTML>

i'm forcing the client to do two hits anyway - might as well have it work right.


I'm running Vue.js on Express/Node. The back-end is running on server port 3300, but we didn't want to expose that publicly.

I installed the requirements (Application Request Writing and URL Rewrite) and then added an Inbound Rule to rewrite the back-end requests to Express, but I kept getting 405 (Method not allowed).

Eventually I got it going by gleaning a few ideas from Stefano Scerra's Blog.

Here's my final web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Handle History Mode and custom 404/500" stopProcessing="true">
          <match url="(.*)" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true"/>
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
        <rule name="api" stopProcessing="true">
            <match url="^api/(.*)$" />
            <action type="Rewrite" url="http://10.1.1.217:3300/{R:1}" logRewrittenUrl="true" />
        </rule>
      </rules>
    </rewrite>
        <tracing>
            <traceFailedRequests>
                <add path="*">
                    <traceAreas>
                        <add provider="WWW Server" areas="Filter" verbosity="Verbose" />
                    </traceAreas>
                    <failureDefinitions timeTaken="00:00:00" statusCodes="100-999" />
                </add>
            </traceFailedRequests>
        </tracing>
  </system.webServer>
</configuration>
0

精彩评论

暂无评论...
验证码 换一张
取 消