以编程方式下载表单生成的文件

本文关键字:文件 表单 编程 方式 下载 | 更新日期: 2023-09-27 18:15:45

我试图以编程方式下载从用户输入(HTML表单)在网站上生成的文件。该网站需要用户登录。

我已经研究了使用篡改数据Firefox插件的网站是如何工作的,这基本上就是在Firefox中手动下载时发生的事情:

  • 我进入了网站的主页
  • 我输入我的凭据,点击"登录"
  • 这触发一个POST请求到URL a,并设置一个"ids"(会话ID我猜)cookie(在其他中)
  • 我打开下载文件的页面
  • 我输入一些东西(文件格式等)
  • 点击"下载"
  • 这触发了一个POST请求到URL B(一个ASP页面)。响应代码为200,包含文件。

通过篡改对URL B的POST请求,我已经确保ids cookie是请求成功所需的唯一cookie。如果ids值不正确或不存在,则响应代码为302,我将被重定向到URL A,并且我似乎仍然登录(显示我的名字)。如果我在POST数据(最初来自表单)中放入垃圾,我可以到达正确的ASP页面,但它显示一个错误。

现在我尝试用c#做下载,而不做我认为不必要的(即。所有的get):

// URL A is loginUrl, URL B is retrieveUrl
public void RetrieveFile(
        string loginUrl, IDictionary<string, string> loginData, 
        string retrieveUrl, IDictionary<string, string> retrieveData) {
    var cookies = new CookieContainer();
    var loginRequest = CreatePostRequest(loginUrl, loginData);
    loginRequest.CookieContainer = cookies;
    var loginResponse = loginRequest.GetResponse();
    loginResponse.Close();
    var retrieveRequest = CreatePostRequest(retrieveUrl, retrieveData);
    retrieveRequest.CookieContainer = cookies;
    var response = retrieveRequest.GetResponse();
    using (
            Stream responseStream = response.GetResponseStream(),
            outputFile = new FileStream("response.html", FileMode.Create)) {
        responseStream.CopyTo(outputFile);
    }
}
private HttpWebRequest CreatePostRequest(string url, IDictionary<string, string> data) {
    var request = (HttpWebRequest)WebRequest.Create(url);
    request.KeepAlive = true;
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    var postData = EncodePostData(data);
    request.ContentLength = postData.Length;
    return request;
}
private byte[] EncodePostData(IDictionary<string, string> data) {
    var dataAsStrings =
        from entry in data
        select String.Format("{0}={1}", entry.Key, entry.Value);
    var dataAsString = String.Join("&", dataAsStrings);
    // Encode in Latin-1 / ISO 8859-1
    var dataAsBytes = Encoding.GetEncoding(1252).GetBytes(dataAsString);
    return dataAsBytes;
}

发生的情况是"response.html"包含位于URL A的页面,就像ids cookie的值错误或不存在一样。但是,如果我在loginRequest.GetResponse()之后打印cookies中存在的所有cookie,则存在ids。我做错了什么吗?

以编程方式下载表单生成的文件

因为这是一个POST请求,我想知道网站是否验证HTTP_REFERER标头,如果不在同一域(或空!),基本上不会将您的请求视为有效,导致您所看到的行为。

你可以尝试在你的检索请求上欺骗HTTP_REFERER报头,看看会发生什么。

retrieveRequest.Referer = "http://www.originatingdomain.com";

这看起来不像是将最初从loginRequest检索到的cookie传递给retriverequest处理程序。

改变
retrieveRequest.CookieContainer = cookies;

retrieveRequest.CookieContainer = loginRequest.CookieContainer;

,看看会发生什么