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 POST
s. 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.1
200 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>
精彩评论