以编程方式下载表单生成的文件
本文关键字:文件 表单 编程 方式 下载 | 更新日期: 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;
,看看会发生什么