【问题标题】:Complete fields via boundary on HttpWebRequests通过 HttpWebRequests 上的边界完成字段
【发布时间】:2014-06-13 07:50:06
【问题描述】:

我正在尝试通过我的 C# 应用程序中的 HttpWebRequests 登录网站。登录页面的post数据如下:

-----------------------------18327245165630\r\n
Content-Disposition: form-data; name="user"\r\n
\r\n
123\r\n
-----------------------------18327245165630\r\n
Content-Disposition: form-data; name="pass"\r\n
\r\n
1234\r\n
-----------------------------18327245165630\r\n
Content-Disposition: form-data; name="mode"\r\n
\r\n
login\r\n
-----------------------------18327245165630\r\n
Content-Disposition: form-data; name="submit"\r\n
\r\n
Submit\r\n
-----------------------------18327245165630--\r\n

字段为userpass,浏览器填写的值为1231234。 p>

问题是如何通过 HttpWebRequests 发送这些值?

我的代码如下:

private void loginButton_Click(object sender, EventArgs e)
{
    try
    {
        HttpWebRequest oRequest = null;
        oRequest = (HttpWebRequest)HttpWebRequest.Create(loginLinkPost);
        oRequest.ContentType = "multipart/form-data; boundary=" + PostData.boundary;
        oRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0";

        oRequest.KeepAlive = true;
        oRequest.AllowAutoRedirect = true;

        oRequest.Method = "POST";
        oRequest.CookieContainer = cookies;
        PostData pData = new PostData();
        Encoding encoding = Encoding.UTF8;
        System.IO.Stream oStream = null;

        pData.Params.Add(new PostDataParam("email", this.usernameBox.Text, PostDataParamType.Field));
        pData.Params.Add(new PostDataParam("password", this.passwordBox.Text, PostDataParamType.Field));
        pData.Params.Add(new PostDataParam("mode", "login", PostDataParamType.Field));
        pData.Params.Add(new PostDataParam("submit", "Submit", PostDataParamType.Field));

        byte[] buffer = encoding.GetBytes(pData.GetPostData());
        oRequest.ContentLength = buffer.Length;
        oStream = oRequest.GetRequestStream();
        oStream.Write(buffer, 0, buffer.Length);
        oStream.Close();

        string sursa = "";
        using (HttpWebResponse oResponse = (HttpWebResponse)oRequest.GetResponse())
        {
            if (oResponse.StatusCode == HttpStatusCode.OK)
            {
                System.IO.Stream responseStream = oResponse.GetResponseStream();
                System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.UTF8);
                sursa = reader.ReadToEnd();
                MessageBox.Show("Logged in :)!");
            }
            else
            {
                setStatus("Server response failed...");
                MessageBox.Show("Server failed to respond!", "Error!");
                setStatus("Ready...");
            }
        }
    }
    catch(Exception ex)
    {
        setStatus("Error while trying to log in...");
        MessageBox.Show(ex.ToString(), "Error when try to login...");
        setStatus("Ready...");
    } 
}

还有 PostData.cs 类:

namespace IPSocksBot
{
    public class PostData
    {
        public static string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");

        private List<PostDataParam> m_Params;

        public List<PostDataParam> Params
        {
            get { return m_Params; }
            set { m_Params = value; }
        }

        public PostData()
        {
            m_Params = new List<PostDataParam>();
        }
        public string GetPostData()
        {
            StringBuilder sb = new StringBuilder();
            foreach (PostDataParam p in m_Params)
            {
                sb.AppendLine("--" + boundary + "\\r\\n");

                if (p.Type == PostDataParamType.File)
                {
                    sb.AppendLine(string.Format("Content-Disposition: file; name=\"{0}\"; filename=\"{1}\"", p.Name, p.FileName));
                    sb.AppendLine("Content-Type: application/octet-stream");
                    sb.AppendLine();
                    sb.AppendLine(p.Value);
                }
                else
                {
                    sb.AppendLine(string.Format("Content-Disposition: form-data; name=\"{0}\"\\r\\n", p.Name));
                    sb.AppendLine("\\r\\n");
                    sb.AppendLine(p.Value + "\\r\\n");
                }
            }

            sb.AppendLine("--" +boundary + "--" + "\\r\\n");

            return sb.ToString();
        }
    }

    public enum PostDataParamType
    {
        Field,
        File
    }

    public class PostDataParam
    {
        public PostDataParam(string name, string value, PostDataParamType type)
        {
            Name = name;
            Value = value;
            Type = type;
        }

        public PostDataParam(string name, string filename, string value, PostDataParamType type)
        {
            Name = name;
            Value = value;
            FileName = filename;
            Type = type;
        }

        public string Name;
        public string FileName;
        public string Value;
        public PostDataParamType Type;
    }
}

我错过了什么?为什么我的值没有提交?我使用 Fiddler 来查看我发送的帖子值,并且完全相同...。

【问题讨论】:

    标签: c# httpwebrequest multipartform-data boundary


    【解决方案1】:

    当我看到您的代码时,我注意到可能导致问题的 2 件事。
    第一:你应该使用相同的名字来发送数据!
    如果你看到浏览器发送 user 你也应该使用它。因此,将 email 更改为 user 并对 pass 字段执行相同操作。

    -----------------------------18327245165630\r\n
    Content-Disposition: form-data; name="user"\r\n
    \r\n
    123\r\n
    

    所以你的代码应该是这样的:

    pData.Params.Add(new PostDataParam("user", this.usernameBox.Text, PostDataParamType.Field));
    pData.Params.Add(new PostDataParam("pass", this.passwordBox.Text, PostDataParamType.Field));
    pData.Params.Add(new PostDataParam("mode", "login", PostDataParamType.Field));
    pData.Params.Add(new PostDataParam("submit", "Submit", PostDataParamType.Field));
    

    我注意到的第二件事是在您的 PostData.cs 类中!
    您应该输入\r\n 而不是\\r\\n

    确保您的请求长度等于 fiddler 发送的请求长度。

    希望对您有所帮助。 最好的问候。

    【讨论】:

    • \\r\\n 是因为我必须转义反斜杠。
    • @curiosul1您会将字符串编码为 UTF-8,为什么需要使用转义字符?\\r\\n 会导致字符串长度增加,这会导致问题!
    • 我不知道为什么,但我已经用 \r\n 替换了 \\r\\n 并且当使用 Fiddler 检查网络表单时,任何请求中都完全缺少 \\r\\n 标记...并且 \n 被替换为请求中的新行...
    • @curiosul \r\n 是换行符!所以它起作用了吗?如果可以,请告诉网址,以便我们提供更多帮助。
    • 我生成的边界看起来像:8d13c0e39a292f8 但从网站捕获的边界都看起来像这样:11692187636794,这应该不是问题,或者?
    猜你喜欢
    • 2014-08-09
    • 1970-01-01
    • 2018-03-04
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多