سؤال

واني اسعى الى تقديم طلبات HTTP من دلفي باستخدام وظائف WININET.

وحتى الآن لدي:

function request:string;
var
  hNet,hURL,hRequest: HINTERNET;
begin
  hNet := InternetOpen(PChar('User Agent'),INTERNET_OPEN_TYPE_PRECONFIG or INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if Assigned(hNet) then 
  begin
  try
    hURL := InternetConnect(hNet,PChar('http://example.com'),INTERNET_DEFAULT_HTTP_PORT,nil,nil,INTERNET_SERVICE_HTTP,0,DWORD(0));
    if(hURL<>nil) then
      hRequest := HttpOpenRequest(hURL, 'POST', PChar('param=value'),'HTTP/1.0',PChar(''), nil, INTERNET_FLAG_RELOAD or INTERNET_FLAG_PRAGMA_NOCACHE,0);
    if(hRequest<>nil) then
      HttpSendRequest(hRequest, nil, 0, nil, 0);
    InternetCloseHandle(hNet);
  except
    on E : Exception do
      ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
  end;
  end
end;

ولكن هذا لا تفعل أي شيء (وأنا استنشاق حركة مرور HTTP الشبكة لمعرفة ما اذا كان يعمل). ولقد استخدمت بنجاح InternetOpenURL ولكن أنا أيضا في حاجة الى ارسال طلب POST وهذه الوظيفة لا تفعل ذلك.

هل يمكن لشخص تبين لي مثال بسيط؟ نتيجة أريده هو الحصول على الصفحة استجابة HTTP في فار كسلسلة.

هل كانت مفيدة؟

المحلول

وحصلت على كل جزء عنوان / اسم الملف عابث مع رمز السابقة. أنا باستخدام هذه من جيف DeVore الآن وانها تعمل بشكل جيد:

function request(const AUrl, AData: AnsiString; blnSSL: Boolean = True): AnsiString;
var
  aBuffer     : Array[0..4096] of Char;
  Header      : TStringStream;
  BufStream   : TMemoryStream;
  sMethod     : AnsiString;
  BytesRead   : Cardinal;
  pSession    : HINTERNET;
  pConnection : HINTERNET;
  pRequest    : HINTERNET;
  parsedURL   : TStringArray;
  port        : Integer;
  flags       : DWord;
begin
  ParsedUrl := ParseUrl(AUrl);

  Result := '';

  pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);

  if Assigned(pSession) then
  try
    if blnSSL then
      Port := INTERNET_DEFAULT_HTTPS_PORT
    else
      Port := INTERNET_DEFAULT_HTTP_PORT;
    pConnection := InternetConnect(pSession, PChar(ParsedUrl[0]), port, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);

    if Assigned(pConnection) then
    try
      if (AData = '') then
        sMethod := 'GET'
      else
        sMethod := 'POST';

      if blnSSL then
        flags := INTERNET_FLAG_SECURE or INTERNET_FLAG_KEEP_CONNECTION
      else
        flags := INTERNET_SERVICE_HTTP;

      pRequest := HTTPOpenRequest(pConnection, PChar(sMethod), PChar(ParsedUrl[1]), nil, nil, nil, flags, 0);

      if Assigned(pRequest) then
      try
        Header := TStringStream.Create('');
        try
          with Header do
          begin
            WriteString('Host: ' + ParsedUrl[0] + sLineBreak);
            WriteString('User-Agent: Custom program 1.0'+SLineBreak);
            WriteString('Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'+SLineBreak);
            WriteString('Accept-Language: en-us,en;q=0.5' + SLineBreak);
            WriteString('Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7'+SLineBreak);
            WriteString('Keep-Alive: 300'+ SLineBreak);
            WriteString('Connection: keep-alive'+ SlineBreak+SLineBreak);
          end;

          HttpAddRequestHeaders(pRequest, PChar(Header.DataString), Length(Header.DataString), HTTP_ADDREQ_FLAG_ADD);

          if HTTPSendRequest(pRequest, nil, 0, Pointer(AData), Length(AData)) then
          begin
            BufStream := TMemoryStream.Create;
            try
              while InternetReadFile(pRequest, @aBuffer, SizeOf(aBuffer), BytesRead) do
              begin
                if (BytesRead = 0) then Break;
                BufStream.Write(aBuffer, BytesRead);
              end;

              aBuffer[0] := #0;
              BufStream.Write(aBuffer, 1);
              Result := PChar(BufStream.Memory);
            finally
              BufStream.Free;
            end;
          end;
        finally
          Header.Free;
        end;
      finally
        InternetCloseHandle(pRequest);
      end;
    finally
      InternetCloseHandle(pConnection);
    end;
  finally
    InternetCloseHandle(pSession);
  end;
end;

وParseUrl هي وظيفة أن انشقاقات URL في "اسم المضيف / اسم الملف" وTStringArray هو مجموعة من السلاسل. لا يزال لدي لمراجعة شفرة غدا لكنها تبدو على ما يرام وفي بلدي الشم رأيت بيانات آخر ورؤوس إرسالها.

نصائح أخرى

وشخصيا انا افضل استخدام مكتبة لجميع من بلدي TCP / IP عمل. على سبيل المثال، وظيفة HTTP بسيطة يمكن أن تكون مشفرة على النحو التالي:

uses
  httpsend;

function testpost;
begin
  stm := tStringstream.create('param=value');
  try
    HttpPostBinary('http://example.com',Stm);
  finally
    stm.free;
  end;
end;

والمكتبة هي مكتوبة بشكل جيد وسهلة جدا لتعديل لتلائم الاحتياجات المحددة الخاصة بك. الإصدار الأخير التخريب يعمل بدون أي مشاكل لكلا دلفي 2009 و 2010. دلفي هذا الإطار ليس عنصر أساس، وإنما هو عبارة عن سلسلة من الفصول الدراسية والإجراءات التي جيدا في بيئة متعددة الخيوط.

والمعلمة الثالث (lpszObjectName) لوينبغي أن يكون HttpOpenRequest لل URL كنت ترغب في طلب. هذا هو السبب تصف وثائق المعلمة الخامسة (lpszReferer) بأنه "مؤشر إلى سلسلة خالية منتهية يحدد URL من المستند الذي تم الحصول على URL في الطلب (lpszObjectName)."

ويحصل على إرسال البيانات التي تم نشرها مع HttpSendRequest . يتم وصف المعلمة lpOptional مثل هذا:

<اقتباس فقرة>   

ومؤشر لالعازلة التي تحتوي على أية بيانات اختيارية ليتم إرسالها مباشرة بعد رؤوس الطلب. يتم استخدام هذه المعلمة بشكل عام لعمليات ما بعد وPUT. يمكن أن تكون البيانات الاختيارية مورد أو المعلومات التي يتم نشرها إلى الخادم. هذه المعلمة يمكن أن تكون فارغة إذا كان هناك أية بيانات اختيارية لإرسال.

والمعلمة الثانية إلى InternetOpen يجب أن يكون <م> فقط اسم الملقم . فإنه لا ينبغي أن يشمل البروتوكول. البروتوكول الذي تحدده مع المعلمة السادسة.

وبعد أن كنت قد أرسلت هذا الطلب، يمكنك قراءة الاستجابة مع InternetReadFile و InternetQueryDataAvailable .

ولا تحقق فقط ما إذا كانت وظائف API تعود الصفر ومن ثم المضي قدما على السطر التالي. إذا فشلوا، والدعوة GetLastError لمعرفة السبب. سوف رمز كنت قد نشرت لا تثير الاستثناءات، لذلك فمن غير المجدي للقبض على أي. (وانه من الحماقة أن "التعامل مع" لهم الطريق كنت تفعل ذلك على أي حال. لا يمسك استثناء أن كنت لا تعرف بالفعل كيفية إصلاح. دعونا كل شيء آخر ترتفع إلى المتصل أو المتصل المتصل، الخ .)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top