有很多关于如何使用WinInet下载文件的文章(这是我从中获取代码的地方),但它们似乎都比较旧和/或已关闭。没有用户名和密码的下载工作正常,但如果我用用户名和密码保护文件夹(使用VodaHost),我在尝试下载文件时不断收到身份验证错误:
401未经授权......
如果我通过网络浏览器访问,会弹出用户名/密码对话框,我可以处理好。受保护的文件夹是:
http://www.mywebsite.com/downloads
我已将服务器设置为:www.mywebsite.com并将网址设置为http://www.mywebsite.com/downloads。用户名和密码已使用网络浏览器进行验证。
我也尝试了许多排列,但我感到有些沮丧。我唯一能想到的是,这是因为服务器不受保护,而是服务器上的文件夹。服务器无法受到保护,因为它可以/可以公开访问。如果您需要更多信息,请告诉我。
有人有什么想法吗?
function Download(Server, Url, User, Pass, FileName : string): boolean;
const
BUFFERSIZE = 4096;
var
hSession: HINTERNET;
hService: HINTERNET;
hHTTP: HINTERNET;
lpBuffer: array[0..BufferSize + 1] of Byte;
BufferLength: DWORD;
dwBytesRead: DWORD;
dwSizeOfRq, Reserved, dwByteToRead: DWORD;
localFile: file;
fsize: DWORD;
begin
try
try
// Downloads file at URL bypassing cache
Result := False;
// Initialize the Win32 Internet functions
hSession := InternetOpen(PChar('Empyrean'), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0) ;
// See if the session handle is valid
if hSession = nil then
Exit;
hHTTP := InternetConnect(hSession, PChar(Server), INTERNET_DEFAULT_HTTP_PORT, PChar(User), PChar(Pass), INTERNET_SERVICE_HTTP, 0, 0);
if hHTTP = nil then
Exit;
// InternetOpenUrl opens a handle to the Internet file using a URL. The flags indicate that the file will always
// be read from the Internet rather than the cache
//hService := InternetOpenUrl(hSession, pChar(url), nil, 0, INTERNET_FLAG_DONT_CACHE or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_RELOAD, 0);
hService := InternetOpenUrl(hSession, pChar(url), nil, 0, INTERNET_FLAG_RELOAD, 0);
// See if the session handle is valid
if hService = nil then
begin
InternetCloseHandle(hService);
Exit;
end;
HttpQueryInfo(hService, HTTP_QUERY_STATUS_CODE or HTTP_QUERY_FLAG_NUMBER, @dwByteToRead, dwSizeOfRq, Reserved);
AssignFile(localFile, FileName);
{$I-}
Rewrite(localFile, 1);
{$I+}
if IOResult <> 0 then
begin
ShowMessage('Cannot create local file: ' + FileName);
InternetCloseHandle(hService);
Exit;
end;
BufferLength := BUFFERSIZE;
// These three variables will store the size of the file, the size of the HttpQueryInfo content, and the number of bytes read in
// total. Now determine the length of a file in bytes
dwByteToRead := 0;
dwSizeOfRq := 4; // BufferLength
Reserved := 0;
// get the file's size.
if not HttpQueryInfo(hService, HTTP_QUERY_CONTENT_LENGTH or HTTP_QUERY_FLAG_NUMBER, @dwByteToRead, dwSizeOfRq, Reserved) then
dwByteToRead := 0;
FSize := 0;
BufferLength := BUFFERSIZE;
while (BufferLength > 0) do
begin
// Read data from the hService handle
if not InternetReadFile(hService, @lpBuffer, BUFFERSIZE, BufferLength) then
Break;
if (BufferLength > 0) and (BufferLength <= BUFFERSIZE) then
BlockWrite(localFile, lpBuffer, BufferLength);
fsize := fsize + BufferLength;
// Check the size of the remaining data. If it is zero, break
if BufferLength > 0 then
Result := True;
end;
CloseFile(localFile);
Result := True;
except
end;
finally
// Close the Internet handle that the application has opened
InternetCloseHandle(hService);
InternetCloseHandle(hSession);
InternetCloseHandle(hHTTP);
end;
end;
答案 0 :(得分:1)
在致电INTERNET_OPTION_USERNAME
之前,使用InternetSetOption()
为INTERNET_OPTION_PASSWORD
返回的句柄指定InternetConnect()
和InternetOpenUrl()
值。
阅读文档以获取更多详细信息:
特别是:
即使需要身份验证,InternetOpenUrl和HttpSendRequest函数也会成功完成。不同的是,头文件和InternetReadFile中返回的数据将收到一个HTML页面,通知用户状态代码。< / p>
因此,如果InternetOpenUrl()
是&#34;成功&#34;,则必须使用HttpQueryInfo()
获取状态代码,如果是401,则设置用户名/密码(提示用户(如果需要)并再次尝试请求。上面的文档中有一个例子。仅当状态代码为200时,响应才会为您提供所请求的实际文件。
答案 1 :(得分:1)
感谢大家的建议。我现在通过在URL中包含用户名/密码来使用代码:
Server := 'www.myServer.com';
URL := 'http://user:pSassword@www.myserver.com/downloads/filetodownload';