2011-12-15 3 views
4

Сегодня меня попросили помочь с проблемой FoxPro, о том, как загрузить файл через HTTP.Загрузить файл (HTTP) с FoxPro

Я нашел две вещи: один был платным ActiveX, а other one требует libcurl.

Есть ли способ сделать это без каких-либо дополнительных (VFP 8), что-то вроде HttpURLConnection в Java? Например, используя Microsoft.XMLHTTP

ответ

0

Посмотрите на использование West Wind Web Connect. Это структура, которая позволит вам написать приложение VFP, доступное из Интернета.

0

Вы можете сделать это в VFP, но для этого требуется регистрация DLL-файлов Windows, чтобы открывать дескрипторы соединений и делать вызовы для получения данных.

Другой вариант - использовать автоматизацию, например, с помощью Internet Explorer. Вы можете создать объект ie из VFP и вызвать его методы для открытия заданного URL-адреса, дождаться завершения «состояния готовности», а затем просмотреть содержимое. Что касается попыток получить вещи, которые требуют строки параметров URL, вы можете добавить их без проблем, но если для этого требуются переменные POST, это немного больше усилий.

Как упоминалось Джерри, инструменты West-Wind достаточно мощные, и Рик Страл делает это с тех пор ... о 1993 году, что я помню. Его другим инструментом является специально wwIPTools.DLL, который предлагает еще больше возможностей.

8

Два фрагмента, которые работают, и не требуют дополнительных файлов/dlls/flls/etc.

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

0

Вариант 1:

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

Просто сделайте Shure, чтобы очистить файл из кэша первого:

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() 

После над кодом выполняется ответ сервера, содержащийся в m.HttpClient.responseBody собственность, и вы можете сохранить значение в файл или, например, для фотоснимков в PictureVal свойство объекта Image:

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

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