-
Delphi Idhttp Post提交 Aspx/Asp.net 时 500错误的解决办法。
添加时间:2013-7-16 点击量:一向应用Delphi写法度,因为习惯了,用起来便利。
然则有一个题目困扰了我半年了。就是应用Idhttp Post提交时辰总会有莫名其妙的错误,大项目组网站没题目,然则一碰到Asp.net就报错500。
想了很多办法,找了很多材料,都没有一个能正确解决我题目的。甚至有人提到了题目的解决纲领,然则最多都只是靠边,没有实际解决掉。
后来无奈,开端应用RTC的HTTP控件,然则RTC没有完美的Cookie经管机制,我费极力量应用IdCookieManager去作为经管器经管他,成果还是有题目,对于一个常规Cookies如下:
Set-Cookie: loginInfo=aabbcc; domain=aaaa.com; expires=Tue, 16-Jul-2013 09:00:20 GMT; path=/;httponly
RTC老是会给他拆分成
Set-Cookie: loginInfo=aabbcc;
Set-Cookie: domain=aaaa.com;
Set-Cookie: expires=Tue, 16-Jul-2013 09:00:20 GMT;
Set-Cookie: path=/;这很让我莫名其妙,我应用嗅探探测是上方的,然则获取Response.headertext的时辰,里面就变成了下面如许。。
第一次碰到空间会直接强迫批改头的。。。然则这还不是最让我愁闷的,当我不管三七二十一,将cookie发送出去时辰,CookieText为:
Cookie:loginInfo=aabbcc;kakaka=aaaaa;bbbb=ccccc;
当发送时变成了如许:
Cookie:loginInfo=aabbcc;
Cookie:kakaka=aaaaa;
Cookie:bbbb=ccccc;这下让我溃散了,这的确是胡扯么,如许办事端底子无确识此外。
可能是对RTC不熟悉吧,若是有人知道解决办法也告诉我下。
下面是重点:
是以我不得不从头开端研究Delphi,起首是解决头文件Accept-Encoding老是附加identity的题目,对DelphiXE2的Indy控件进行了从头编译,改用了Indy10_5022。
批改了idhttp.pas里
if IndyPos(identity, ARequest.AcceptEncoding) = 0 then begin {do not localize}
if ARequest.AcceptEncoding <> then begin
//作废强迫identity
//ARequest.AcceptEncoding := ARequest.AcceptEncoding + , identity; {do not localize}
end else begin
ARequest.AcceptEncoding := identity; {do not localize}
end;
end;的强迫附加代码,当我指定AcceptEncoding时,则遵守我指定的来,不进行附加。
然后发明题目依旧。对错误进行了过滤,然后获取IDHTTP.URL信息,发明地址不是我之前接见的login.aspx,而变成了index.aspx。
一开端我认为是我地址输入错了,然则找遍源代码也没发明index.aspx的处所。
我开端嗅探,在和谈里发了然302跳转,于是想起了以前对这个的研究有发明的这个的题目,也是别人一个帖子里提到的,post->a页面时辰,因为302跳转,则持续post给了下一个跳转的页面。
解析嗅探信息,发明的确如此:
POST /User/index.aspx HTTP/1.1
而接管到的信息是如许的:
HTTP/1.1 500 Internal Server Error
Date: Tue, 16 Jul 2013 08:08:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 7868这个是post给 index.aspx的返回信息,500错误。HTTP内容意思是不法提交导致asp.net的错误。
asp.net有严格的表单验证,若是进行post提交时带有的验证表单参数和地址等信息不合当令,则会报错。
那我就熟悉打听了,正确处理惩罚办法应当是:POST->302->GET正确地址。
我测验测验以下代码:
try
Memo1.Text:=IdHTTP1.Post(http://www..com/User/login.aspx,StrLst,IndyTextEncoding(encUTF8));
except
end;
ShowMessage(IntToStr(IdHTTP1.ResponseCode));
Memo1.Text:=IdHTTP1.Response.RawHeaders.Values[Location];
if IdHTTP1.Response.RawHeaders.Values[Location][1]=/ then
begin
IdHTTP1.URL.Path:=IdHTTP1.Response.RawHeaders.Values[Location];
IdHTTP1.URL.Params:=;
IdHTTP1.URL.Document:=;
tmpUrl:=IdHTTP1.URL.GetFullURI();
end
else if Pos(://,IdHTTP1.Response.RawHeaders.Values[Location])>0 then
begin
tmpUrl:=IdHTTP1.Response.RawHeaders.Values[Location];
end
else if pos(/,IdHTTP1.Response.RawHeaders.Values[Location])=0 then
begin
IdHTTP1.URL.Document:=IdHTTP1.Response.RawHeaders.Values[Location];
IdHTTP1.URL.Params:=;
tmpUrl:=IdHTTP1.URL.GetFullURI();
end;
Memo1.Lines.Add(--------------------------);
Memo1.Lines.Add(IdHTTP1.Get(IdHTTP1.URL.URI));证了然我的设法是正确的,然则莫非每次我都必必要如许一长串代码和不安然的跳转处理惩罚去做跳转么?
这显然不安然,若是呈现我没推敲到的规矩,那么就会有错误。我推敲看看Idhttp源代码里如何处理惩罚的,想做一下批改。成果在源代码里发了然这个:
if ((LResponseCode = 302) and (hoTreat302Like303 in FHTTP.HTTPOptions)) or
(LResponseCode = 303) then
begin
Request.Source := nil;
Request.Method := Id_HTTPMethodGet;
end else begin
Request.Method := LMethod;
end;哈哈,恍然大悟,我对代码做了一下优化:
IdHTTP1.HandleRedirects:=True;
IdHTTP1.ProtocolVersion:=pv1_1;
IdHTTP1.HTTPOptions:=IdHTTP1.HTTPOptions+[hoTreat302Like303];
Memo1.Text:=IdHTTP1.Post(http://www..com/User/login.aspx,StrLst,IndyTextEncoding(encUTF8));运行,一切正常,获取到了正确信息。
不过为什么会如许呢?按照302like303的意思是,当碰到302错误时遵守303进行履行。
百度了下材料如下:
302 作为HTTP1.0的标准,以前叫做Moved Temporarily ,如今叫Found.
如今应用只是为了兼容性的处理惩罚,包含PHP的默认Location重定向用的也是302.
然则HTTP 1.1 有303
和307作为具体的补充,其实是对302的细化
303:对于POST恳求,它默示恳求已经被处理惩罚,客户端可以接着应用GET办法去恳求Location里的URI。这下熟悉打听了,其实实际应当是写代码的人没有正确应用跳转,大多半人直接将302算作303在用。302会持续Method,而303则是再次应用GET。
至此,困扰了我半年的题目终于解决。这半年来我一向无法处理惩罚Asp.net的站点。其原因竟然只是因为一个参数。。。。
因为我没有找到网上对这个题目的处理惩罚办法,写出这篇文章给后来人,以免造成像我如许的杯具。
无论对感情还是对生活,“只要甜不要苦”都是任性而孩子气的,因为我们也不完美,我们也会伤害人。正因为我们都不完美,也因为生活从不是事事如意,所以对这些“瑕疵”的收纳才让我们对生活、对他人的爱变得日益真实而具体。—— 汪冰《世界再亏欠你,也要敢于拥抱幸福》