が設定された場合、リクエストが失敗します
-
29-09-2019 - |
質問
次のケースを検討してください。
- Webサーバーが.NETアプリを実行しています
<sessionState cookieless="AutoDetect" />
. - クライアントは単純なものを使用してデータを投稿しています
HttpWebRequest
(クッキーなし)。
この一見単純なケースは、大きな障害を引き起こします。
.NETは要求エージェントかどうかを判断できないため(HttpWebRequest
)Cookieをサポートすると、次のような場所にある302のリダイレクトを使用して、POSTリクエストに応答します。
- 名前のクッキー
AspxAutoDetectCookie
応答で - 名前のクエリパラメーター
AspxAutoDetectCookie
転送場所で
要求エージェントは、新しい場所を要求することになっています。 HttpWebRequest
します。 .netが表示されるとき AspxAutoDetectCookie
クエリ文字列では、これが再リケストであることがわかっています。 AspxAutoDetectCookie
リクエストヘッダーにあります。
問題は、ほとんどの要求エージェント(Webブラウザ、 HttpWebRequest
)303が他の人を見る303であるかのように扱い、元のHTTPメソッドに関係なく、再リケストを取得します!最初のPOSTリクエストで送信されたデータはすべて転送されません。
正しい応答は307一時的なリダイレクトである必要がありますが、これは要求方法を変更しません。 (ロケーションXへの投稿リクエストXへのリダイレクト 役職 場所Yへのリクエスト。)
.NETでこの動作を変更する方法はありますか?投稿リクエストは破壊されませんか?
解決
私がこれに見ることができる唯一の解決策は追加することです AspxAutoDetectCookie=1
すべての投稿リクエストに。
これにより、ASP.NETはリクエストをリダイレクトすることはなく、302対307の質問を完全に回避できます。クッキーがリクエストに埋め込まれている場合、ASP.NETはCookieがサポートされていることを検出し、Cookieが埋め込まれていない場合、そうでないと仮定します。
他のヒント
cookieless = "sudeviceprofile"の使用に問題はありますか?回避策として使用できます。
また、Cookiless = trueの場合に問題が表示されます。あなたは本当に私を助けてくれました。私のweb.configからtrueにsessionState Cookilessを設定し、問題が修正され、私の結果をグーグルで検索してこのページを見つけたまで、この問題が何が原因であるのかさえ把握できませんでした。このラインを削除することで問題が解決する理由を説明するのに役立ちました。セッション状態の使用方法を変更することを伴わないソリューションを見つけたら教えていただけますか?
スレッドが古いことはわかっていますが、もう1つの実行可能なソリューションは、CookielessよりもHTTP投稿を修正するためにHTTPモジュールを作成して作成することです。
これが私が使用するものです
using System;
using System.Collections.Specialized;
using System.Web;
using System.Web.SessionState;
using System.IO;
using System.Text;
namespace CustomModule
{
public sealed class CookielessPostFixModule : IHttpModule
{
public void Init (HttpApplication application)
{
application.EndRequest += new
EventHandler(this.Application_EndRequest);
}
private string ConstructPostRedirection(HttpRequest req,
HttpResponse res)
{
StringBuilder build = new StringBuilder();
build.Append(
"<html>\n<body>\n<form name='Redirect' method='post' action='");
build.Append(res.ApplyAppPathModifier(req.Url.PathAndQuery));
build.Append("' id='Redirect' >");
foreach (object obj in req.Form)
{
build.Append(string.Format(
"\n<input type='hidden' name='{0}' value = '{1}'>",
(string)obj,req.Form[(string)obj]));
}
build.Append(
"\n<noscript><h2>Object moved <input type='submit' value='here'></h2></noscript>");
build.Append(@"</form>"+
"<script language='javascript'>"+
"<!--"+
"document.Redirect.submit();"+
"// -->"+
"</script>");
build.Append("</body></html>");
return build.ToString();
}
private bool IsSessionAcquired
{
get
{
return (HttpContext.Current.Items["AspCookielessSession"]!=null &&
HttpContext.Current.Items["AspCookielessSession"].ToString().Length>0);
}
}
private string ConstructPathAndQuery(string[] segments)
{
StringBuilder build = new StringBuilder();
for (int i=0;i<segments.Length;i++)
{
if (!segments[i].StartsWith("(")
&& !segments[i].EndsWith(")"))
build.Append(segments[i]);
}
return build.ToString();
}
private bool IsCallingSelf(Uri referer,Uri newpage)
{
if(referer==null || newpage==null)
return false;
string refpathandquery = ConstructPathAndQuery(
referer.Segments);
return refpathandquery == newpage.PathAndQuery;
}
private bool ShouldRedirect
{
get
{
HttpRequest req = HttpContext.Current.Request;
return (!IsSessionAcquired
&& req.RequestType.ToUpper() == "POST"
&& !IsCallingSelf(req.UrlReferrer,req.Url));
}
}
private void Application_EndRequest(Object source, EventArgs e)
{
HttpRequest req = HttpContext.Current.Request;
HttpResponse res = HttpContext.Current.Response;
if (!ShouldRedirect) return;
res.ClearContent();
res.ClearHeaders();
res.Output.Flush();
char[] chr = ConstructPostRedirection(req,res).ToCharArray();
res.Write(chr,0,chr.Length);
}
public void Dispose()
{}
}
}