Delphi 7 idHTTP JSON 数据空结果

Delphi 7 idHTTP JSON Data Null Result

主要目标是将所有数据发送到远程 mysql 数据库。 我正在为 POST 方法使用 TidHTTP。拥有近 10.000 条记录,大约 2MB 数据。当我运行delphi代码,上传json数据。但是有些记录没有插入。

Delphi 代码:

function TFrmUploadDataWithJSON.PostJS(JS: string): string;
var
  lStream: TStringStream;
  parameters: TStringList;

begin
  IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded';
  lStream := TStringStream.Create(Result);
  try
    Parameters := TStringList.Create;
    parameters.Add('js=' + JS);
    IdHTTP1.Post('http://domain.com/uploadi.php', parameters,lStream);
    lStream.Position := 0;
    Result := lStream.ReadString(lStream.Size);
  finally
    //FreeAndNil(lHTTP);
    FreeAndNil(lStream);
  end;
end;

更新 1:PHP 边 这些更新后,我收到 "not parsed" 回复。大约 2.5 MB 是 JSON Parse 的大数据?

此处代码:

<?php
  include_once dirname(__FILE__) .'/DBConnect.php';

  function update($json){    
    $db = new DbConnect();

    $response = array();
    $res=array();

    if($json!=null){
      $done = 0;
      $fail = 0;

      $mErr = "";

      $decoded=json_decode($json,true);

      //$decode= var_dump($decoded);
      //$ss=$decode["array"];
      //echo $decoded['number'];
      if(is_array($decoded["items"]))
      {
        foreach($decoded["items"] as $items)
        {
          $a=$items["a"];
          $b=$items["b"];

          mysql_query("delete from `items` where `code` = '$a'") or $mErr = $mErr ."-". mysql_error();        
          //header("Content-Type: application/json; charset=utf-8", true);

          $sqlstr = "INSERT INTO items (`code`, `numune_id`) VALUES ('$a', '$b')";

          $result = mysql_query($sqlstr) or  $mErr = $mErr ."-". mysql_error();
          if ($result) {
            $done = $done + 1;
          } else {
            $fail = $fail + 1;
          }
        }

        $response["done"] = $done;
        $response["fail"] = $fail;
        $response["mysql errors"] =  $mErr;
        if ($fail > 0) 
          $response["error"] = "must be repost";

      } else {
        $response["error"] = "json not parsed";
      }
    } else {      
      $response["error"] = "json not posted";

    }

    // echoing JSON response
    echo json_encode($response);
  }


    update($_POST["js"]);

?>

更新 2:Delphi 边 我将 ContentType 更改为“application/json”。并通过原始数据获取 json 数据。但是仍然 json 数据没有解码。

function PostJS(AFormat, JS: string): string;
var
  IdHTTP: TIdHTTP;
  RBody: TStringStream;
  params: TStringList;

begin
  IdHTTP := TIdHTTP.Create(self);
  RBody := TStringStream.Create(Result);

  IdHTTP.OnWork := IdHTTP1Work;
  IdHTTP.OnWorkBegin := IdHTTP1WorkBegin;
  IdHTTP.OnWorkEnd := IdHTTP1WorkEnd;

  try
    Params := TStringList.Create;
    params.Add('js=' + JS);
    params.Add('command=a1b234lTrLKMDEk');

    if AFormat = 'json' then
    begin
      IdHTTP.Request.Accept := 'text/javascript';
      IdHTTP.Request.ContentType := 'application/json';
      IdHTTP.Request.ContentEncoding := 'utf-8';
    end
    else
    begin
      IdHTTP.Request.Accept := 'text/xml';
      IdHTTP.Request.ContentType := 'text/xml';
      IdHTTP.Request.ContentEncoding := 'utf-8';
    end;

    IdHTTP.Post('http://domain.com/upload.php',params, RBody);

    RBody.Position := 0;
    Result := RBody.ReadString(RBody.Size);
  finally
    FreeAndNil(RBody);
    FreeAndNil(IdHTTP);
  end;
end;

PHP 边: 我想我是对的。 json_last_error() 告诉我为什么不解码它。

<?php
  include_once dirname(__FILE__) .'/DBConnect.php';

  function update($json){    

    $db = new DbConnect();

    $response = array();
    $res=array();

    if($json!=null){
      $done = 0;
      $fail = 0; 

      $mErr = "";

      $decoded=json_decode($json,true);

      if(is_array($decoded["items"]))
      {
        foreach($decoded["items"] as $items)
        {
          $a=$items["a"];
          $b=$items["b"];


          mysql_query("delete from `items` where `code` = '$a'") or $mErr = $mErr ."-". mysql_error();        

          $sqlstr = "INSERT INTO items (`code`, `numune_id`) VALUES ('$a', '$b')";

          $result = mysql_query($sqlstr) or  $mErr = $mErr ."-". mysql_error();
          if ($result) {
            $done = $done + 1;
          } else {
            $fail = $fail + 1;
          }
        }

        $response["done"] = $done;
        $response["fail"] = $fail;
        $response["mysql err"] =  $mErr;
        if ($fail > 0) 
          $response["error"] = "must be repost";

      } else {

        $response["error"] = "json not parsed";
        switch (json_last_error()) {
            case JSON_ERROR_NONE:
                $e1= ' - No errors';
            break;
            case JSON_ERROR_DEPTH:
                $e1= ' - Maximum stack depth exceeded';
            break;
            case JSON_ERROR_STATE_MISMATCH:
                $e1= ' - Underflow or the modes mismatch';
            break;
            case JSON_ERROR_CTRL_CHAR:
                $e1= ' - Unexpected control character found';
            break;
            case JSON_ERROR_SYNTAX:
                $e1= ' - Syntax error, malformed JSON';
            break;
            case JSON_ERROR_UTF8:
                $e1= ' - Malformed UTF-8 characters, possibly incorrectly encoded';
            break;
            default:
                $e1= ' - Unknown error';
            break;
        }
        $response["message"] =$e1;
        $response["json"] = $json;
      }
    } else {       
      $response["error"] = "json not posted";

    }

    // echoing JSON response
    echo json_encode($response);
  }

  parse_str(file_get_contents("php://input"),$post_vars);

  if ($post_vars["command"] == 'a1b234lTrLKMDEk') {
    update($post_vars["js"]);
  } 
?>

**我找到原因了。简单的原因是 indy 组件版本。 ** 我将我的代码升级到 Delphi xe7,现在可以了。

您的 HTTP 客户端需要使用不同的方式来传输 JSON 数据。这是一个基本示例:

uses
  IdHTTP, IdGlobal, SysUtils, Classes;

var
  HTTP: TIdHTTP;
  RequestBody: TStream;
  ResponseBody: string;
begin
  HTTP := TIdHTTP.Create;
  try
    try
      RequestBody := TStringStream.Create('{... (JSON) ...}', // (1)
        TEncoding.UTF8); // (2)
      try
        HTTP.Request.Accept := 'application/json';
        HTTP.Request.ContentType := 'application/json';
        ResponseBody := HTTP.Post('http://example.com/post', RequestBody);
      finally
        RequestBody.Free;
      end;
      WriteLn(ResponseBody);
      WriteLn(HTTP.ResponseText);
    except
      on E: EIdHTTPProtocolException do
      begin
        WriteLn(E.Message);
        WriteLn(E.ErrorMessage);
      end;
      on E: Exception do
      begin
        WriteLn(E.Message);
      end;
    end;
  finally
    HTTP.Free;
  end;
end.

备注:

  • (1) 您不得在 JSON 正文中使用 TStringList。该版本的 TIdHTTP.Post() 根据 application/x-www-form-urlencoded 媒体类型格式化数据,这不适合 JSON 并且会损坏它。

  • (2) 确保将 JSON 正文编码为 UTF-8。