2011-12-15 258 views
4

今天,我被问及如何通过HTTP下载文件的FoxPro问题的帮助。使用FoxPro下载文件(HTTP)

我发现了两件事:一个是付费的ActiveX,而other one需要libcurl。

有没有办法做到这一点,没有任何额外的(VFP 8),类似于Java中的HttpURLConnection?例如通过使用Microsoft.XMLHTTP

回答

0

使用West Wind Web Connect进行研究。这是一个框架,可以让您编写可从Web访问的VFP应用程序。

0

您可以在VFP中做到这一点,但它需要注册Windows DLL才能打开连接句柄,并调用以获取数据。

另一种选择是使用自动化,如使用Internet Explorer。您可以从VFP中创建一个ie对象,并调用其方法来打开给定的URL,等到它的“就绪状态”完成,然后查看内容。至于尝试获取需要URL参数字符串的东西,您可以添加这些没有问题,但如果它需要POST变量,这是多一点努力。

正如杰瑞所说,西风工具非常强大,里克斯特拉尔自从1993年以来一直这样做,我记得。他的另一个工具是wwIPTools.DLL,它提供了更多的功能。

8

两个片段可以工作,并且不需要额外的文件/ dlls/flls /等。

Local loRequest, lcUrl, lcFilename 

lcUrl = "http://example.com/foo.zip" 
lcFilename = "C:\Temp\PSV.zip" 

loRequest = Createobject('MsXml2.XmlHttp') 
loRequest.Open("GET",lcUrl,.F.) 
loRequest.Send() 
StrToFile(loRequest.ResponseBody,lcFilename) 

lox = CREATEOBJECT("inetctls.inet") 
lcSuff = lox.OpenURL("http://whatever.co.uk/suff.htm") 
STRTOFILE(lcStuff, "c:\data\myfile.htm") 

(从here拍摄)

0

你也可以看看克雷格博伊德的免费VFPConnection库,他也有一个很好的免费的JSON库。

+0

这就是我在我原来的问题粘贴的链接。唉,最新的版本不起作用。 – Bozho 2011-12-16 09:34:50

0

选项1:

Declare Integer URLDownloadToFile In urlmon.dll As _apiURLDownloadToFile; 
Integer pCaller, ; 
String szURL, ; 
String szFileName, ; 
Integer dwReserved, ; 
Integer lpfnCB 

只是要舒尔以清除缓存第一个文件:

Declare Integer DeleteUrlCacheEntry In wininet.dll As _apiDeleteUrlCacheEntry ; 
    String lpszUrlName 

或在URL中,如“末尾添加一个随机的参数?例如“somerandomvalue”。

选项2:

Declare Integer InternetOpen In wininet.dll As _apiInternetOpen ; 
    String lpszAgent, ; 
    Integer dwAccessType, ; 
    String lpszProxy, ; 
    String lpszProxyBypass, ; 
    Integer dwFlags 

Declare Integer InternetOpenUrl In wininet.dll As _apiInternetOpenUrl ; 
    Integer hInternet,; 
    String lpszUrl,; 
    String lpszHeaders,; 
    Integer dwHeadersLength,; 
    Integer dwFlags,; 
    Integer dwContext 

Declare Integer InternetReadFile In wininet.dll As _apiInternetReadFile ; 
    Integer hFile, ; 
    String @lpBuffer, ; 
    Integer dwNumberOfBytesToRead, ; 
    Integer @lpdwNumberOfBytesRead 

Declare Integer InternetCloseHandle In wininet.dll As _apiInternetCloseHandle ; 
    Integer hInternet 

的函数的适当使用可以在MSDN上找到。

PS:你错过了这一个:http://curl.haxx.se/libcurl/foxpro/

1

是一个我HttpClient.prg文件(仅支持GET响应):

#define INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 

#define REQ_STATE_UNINITIALIZED 0 && open()has not been called yet. 
#define REQ_STATE_LOADING  1 && send()has not been called yet. 
#define REQ_STATE_LOADED  2 && send() has been called, and headers and status are available. 
#define REQ_STATE_INTERACTIVE 3 && Downloading; responseText holds partial data. 
#define REQ_STATE_COMPLETED  4 && The operation is complete. 

DEFINE CLASS HttpClientRequest As Custom 
    readystate=REQ_STATE_UNINITIALIZED 
    Protocol=NULL 
    Url=NULL 
    requestBody=NULL 
    responseBody=NULL 

    PROCEDURE Open(tcProtocol, tcUrl) 
    IF this.readystate != REQ_STATE_UNINITIALIZED 
     ERROR "HttpClientRequest is already opened." 
    ENDIF 
    IF VARTYPE(m.tcProtocol)!="C" OR VARTYPE(m.tcUrl)!="C" 
     ERROR "Invalid type or count of parameters." 
    ENDIF 
    IF NOT INLIST(m.tcProtocol,"GET") 
     ERROR "Unsupported or currently not implemented protocol type." 
    ENDIF 
    this.Protocol = m.tcProtocol 
    this.Url = m.tcUrl 
    this.readystate = REQ_STATE_LOADING 
    ENDPROC 

    PROCEDURE Send(tcBody) 
    IF this.readystate != REQ_STATE_LOADING 
     ERROR "HttpClientRequest is not in initialized state." 
    ENDIF 
    IF PCOUNT()=0 
     m.tcBody=NULL 
    ENDIF 
    IF this.Protocol=="GET" AND (NOT ISNULL(m.tcBody)) 
     ERROR "Invalid type or count of parameters." 
    ENDIF 
    this.requestBody = m.tcBody 
    this.readystate = REQ_STATE_LOADED 


    DECLARE integer InternetOpen IN "wininet.dll" ; 
     string @ lpszAgent, ; 
     integer dwAccessType, ; 
     string @ lpszProxyName, ; 
     string @ lpszProxyBypass, ; 
     integer dwFlags 
    DECLARE integer InternetCloseHandle IN "wininet.dll" ; 
     integer hInternet 
    DECLARE integer InternetCanonicalizeUrl IN "wininet.dll" ; 
     string @ lpszUrl, ; 
     string @ lpszBuffer, ; 
     integer @ lpdwBufferLength, ; 
     integer dwFlags 
    DECLARE integer InternetOpenUrl IN "wininet.dll" ; 
     integer hInternet, ; 
     string @ lpszUrl, ; 
     string @ lpszHeaders, ; 
     integer dwHeadersLength, ; 
     integer dwFlags, ; 
     integer dwContext 
    DECLARE integer InternetReadFile IN "wininet.dll" ; 
     integer hFile, ; 
     string @ lpBuffer, ; 
     integer dwNumberOfBytesToRead, ; 
     integer @ lpdwNumberOfBytesRead 

    LOCAL m.hInternet,lcUrl,lnUrlLen,m.hInternetFile,lcBuffer,lnBufferLen,lnReaded 
    m.hInternet = InternetOpen("a.k.d. HttpClientRequest for Visual FoxPro", ; 
           INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY, ; 
           NULL, NULL, 0) 
    this.responseBody = "" 
    IF m.hInternet != 0 
     m.lnUrlLen = LEN(this.Url)*8 
     m.lcUrl = REPLICATE(CHR(0),m.lnUrlLen) 
     InternetCanonicalizeUrl(this.Url, @lcUrl, @lnUrlLen, 0) 
     m.hInternetFile = InternetOpenUrl(m.hInternet, @lcUrl, NULL, -1, 0, 0) 
     IF m.hInternetFile != 0 
     m.lnBufferLen = 10240 
     DO WHILE .T. 
      m.lcBuffer = REPLICATE(CHR(0),m.lnBufferLen) 
      m.lnReaded = 0 
      IF NOT (0!=InternetReadFile(m.hInternetFile, @lcBuffer, m.lnBufferLen, @lnReaded) AND m.lnReaded>0) 
      EXIT 
      ENDIF 
      this.responseBody = this.responseBody + LEFT(m.lcBuffer,m.lnReaded) 
      this.readystate = REQ_STATE_INTERACTIVE 
     ENDDO 
     InternetCloseHandle(m.hInternetFile) 
     ENDIF 
     InternetCloseHandle(m.hInternet) 
    ENDIF 
    this.readystate = REQ_STATE_COMPLETED 
    ENDPROC 
ENDDEFINE 

GET请求用法:

Local HttpClient 
m.HttpClient = NEWOBJECT("HttpClientRequest","httpclient.prg") 
m.HttpClient.Open("GET","http://servername/path/resourcename") 
m.HttpClient.Send() 

后上面的代码被执行包含在中的服务器响应财产,你可以值保存到文件或例如用于图片到图片对象PictureVal属性:

STRTOFILE(m.HttpClient.responseBody,"c:\filename"); 

m.myform.AddObject("myimg",""image") 
m.myform.myimg.PictureVal=m.HttpClient.responseBody