我正在尝试让我的应用程序在外部网站上执行登录操作。我使用以下代码:
Dim enc As Encoding = Encoding.UTF8
Dim Data As Byte() = Nothing
Dim req As HttpWebRequest
req = CType(Net.WebRequest.Create(URL), Net.HttpWebRequest)
req.Method = method
req.CookieContainer = CookieJar
req.AllowAutoRedirect = False
If method = "POST" Then
req.ContentType = "application/x-www-form-urlencoded"
Data = enc.GetBytes(PostData)
If Data.Length > 0 Then
req.ContentLength = Data.Length
Dim newStream As Stream = req.GetRequestStream()
newStream.Write(Data, 0, Data.Length)
newStream.Flush()
newStream.Close()
End If
End If
Dim Response As Net.HttpWebResponse = CType(req.GetResponse(), Net.HttpWebResponse)
Dim ResponseStream As IO.StreamReader = New IO.StreamReader(Response.GetResponseStream(), enc)
Dim Html As String = ResponseStream.ReadToEnd()
Response.Close()
ResponseStream.Close()
Return Html
什么有效:
什么行不通:
未发送的cookie就是这个:
Set-Cookie: mpSecurity="ODc2NzM2ODoxMzUODViNTg5OWM1NTNlOWMwYmMxYjUxNWZjYzJjOGQyZGU4MTc2M2M=";Version=1;Path=/;Domain=.xxxxx.nl;Discard
此Cookie与正确发送的Cookie之间的唯一区别是,其中包含“Version = 1”和“Discard”...
有没有人知道为什么除了上面提到的所有检索到的cookie之外都会被发送?
任何帮助将不胜感激!
答案 0 :(得分:2)
这是CookieContainer中常见的已知错误:Link Here for .Net version 4.0以下
注意Set-Cookie标头的域名:
Cookie # 1 -> Set-Cookie: mpSecurity="ODc2NzM2ODoxMzUODViNTg5OWM1NTNlOWMwYmMxYjUxNWZjYzJjOGQyZGU4MTc2M2M=";Version=1;Path=/;Domain=marktplaats.nl;Discard
Cookie # 2 -> Set-Cookie: mpSecurity="ODc2NzM2ODoxMzUODViNTg5OWM1NTNlOWMwYmMxYjUxNWZjYzJjOGQyZGU4MTc2M2M=";Version=1;Path=/;Domain=.marktplaats.nl;Discard
当网址格式类似于http://marktplaats.nl/...
时,会发送Cookie#1
当URL格式类似于http://www.marktplaats.nl/...
class DomainComparer : StringComparer
{
public override int Compare(string x, string y)
{
if (x == null || y == null)
{
return StringComparer.OrdinalIgnoreCase.Compare(x, y);
}
if (x.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
{
x = x.Substring(4);
}
if (y.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
{
y = y.Substring(4);
}
return StringComparer.OrdinalIgnoreCase.Compare(x, y);
}
public override bool Equals(string x, string y)
{
return Compare(x, y) == 0;
}
public override int GetHashCode(string obj)
{
if (obj.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
{
obj = obj.Substring(4);
}
return StringComparer.OrdinalIgnoreCase.GetHashCode(obj);
}
}
/// <summary>
/// this is a hackfix for microsoft bug, where cookies are not shared between www.domain.com and domain.com
/// </summary>
/// <param name="cc"></param>
static void ImproveCookieContainer(ref CookieContainer cc)
{
Hashtable table = (Hashtable)cc.GetType().InvokeMember(
"m_domainTable",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance,
null, cc, new object[] { });
var comparerPreperty = table.GetType().GetField("_keycomparer",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance);
if (comparerPreperty != null)
{
comparerPreperty.SetValue(table, new DomainComparer());
}
}
解决方案#1的实现,每当你创建一个CookieContainer实例时,只需调用一次方法
void main()
{
CookieContainer cookieJar = new CookieContainer();
ImproveCookieContainer(ref cookieJar);
// then use it with the WebRequest object
}
每次向容器添加cookie时调用BugFix_CookieDomain 在使用.GetCookie之前或系统使用容器之前。
private void BugFix_CookieDomain(CookieContainer cookieContainer)
{
System.Type _ContainerType = typeof(CookieContainer);
Hashtable table = (Hashtable)_ContainerType.InvokeMember("m_domainTable",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.GetField |
System.Reflection.BindingFlags.Instance,
null,
cookieContainer,
new object[] { });
ArrayList keys = new ArrayList(table.Keys);
foreach (string keyObj in keys)
{
string key = (keyObj as string);
if (key[0] == '.')
{
string newKey = key.Remove(0, 1);
table[newKey] = table[keyObj];
}
}
}
答案 1 :(得分:1)
决定为此/类似案例发布另一个解决方法,以防有人发现它有用。
我遇到了同样的问题,收到了三个Cookie,只有两个显示为从下一个网络请求发送的。我做了一些调试,发现我的错误不是域本身,因为之前的答案表明 - 在我的情况下,问题是返回的第三个cookie并且未在后续请求中重用被设置为HTTPS重定向,它将“Secure”属性设置为true。所以 我所要做的就是将下一个请求网址从http:// ....更改为https:// .... ,然后所有的cookie都是发送过来,一切正常。
希望它有所帮助!