2016-08-20 7 views
0

я столкнулся несколько сайтов, которые использует JSON для запроса и ответа
я встречаю двух типов:
1-application/x-www-form-urlencoded как запрос и возвращает ответ типа application/json контента
2-application/json тип контента как для запроса и ответа в type 1
я попытался изменить тип ответного контента с использованием
mIdHttp.Response.ContentType := 'application/json';
, но с помощью http-анализатора я вижу, что он не изменяется, и его все еще text/html
теперь я не знаю, связана ли проблема с тем, что я не могу изменить тип контента или нет, но я не знаю, как это сделать с json!
Несколько вопросов относительно json:
1- Должен ли я кодировать данные json при публикации? как ?
2- Как я могу разобрать код ответа json? как его получить ? нужна ли какая-то кодировка или специальное преобразование?
3- какая настройка idhttp для json изменяется с каждым сайтом и нуждается в настройке?IdHttp: как бороться с запросом JSon и ответ

Я понимаю, что мои вопросы звучат немного повсеместно, но все остальные вопросы очень специфичны и не объясняют основы при работе с типом контента 'application/json'.

Edit 1:
благодаря Реми Лебо ответ я был в состоянии успешно работать с type 1
, но я до сих пор проблемы с отправкой JSON запрос, может кто-то пожалуйста, поделитесь в рабочий пример, это один из сайты размещения информации, пожалуйста, используйте это для примера:
enter image description here

Одно важное замечание: этого конкретного сайта и после запроса Conte nt точно подобны друг другу! и это расстраивает меня, потому что на сайте, я укажу start date и end date затем нажмите на folder like icon и это post отправляется (тот, который вы можете увидеть выше), и result должен быть links (и это) но вместо появляются только в request content, они также отображаются в post! (также я пытаюсь получить ссылки, но на post ссылки, что я хочу, также отправляются, как я могу отправить что-то, чего у меня нет?)

только для большей ясности здесь место я заполнить дату и значок я упомянул:
enter image description here

+0

Универсального решения нет. Каждая реализация может отличаться. Вы можете контролировать, хотите ли вы Indy кодировать параметры с помощью 'hoForceEncodeParams' в' FHTTP.HTTPOptions' (если вы отправляете данные JSON в свой запрос, многие сайты не разрешают кодированный запрос). Не следует устанавливать «Response.ContentType». Это то, что сервер возвращает. Вы должны установить 'Request.ContentType' (то, что вы отправляете) и' Request.Accept' (что вы ожидаете от сервера) – smooty86

+0

@ smooty86 флаг 'hoForceEncodeParams' применяется только при публикации' TStrings' в 'application/x-www -форма-urlencoded'. В этой ситуации это не применяется, поскольку вы не можете публиковать JSON с помощью 'TStrings', вместо этого вы должны использовать' TStream'. –

+0

@RemyLebeau, вы ставите, я могу отправить JSON в TStrings :) Хотя я понимаю, что это может быть менее эффективным. – smooty86

ответ

7

Вы не можете указать формат ответ, если запрашиваемый ресурс не дает явный входной параметр или выделенный URL для этой точной цели (т.е. для запроса ответа, отправляемого как html, xml, json и т. д.). Установка свойства TIdHTTP.Response.ContentType бесполезна. Он будет перезаписан фактическим заголовком Content-Type ответа.

Чтобы отправить JSON в запросе, вы должны опубликовать его в качестве TStream, как TMemoryStream или TStringStream и установить TIdHTTP.Request.ContentType по мере необходимости, например:

var 
    ReqJson: TStringStream; 
begin 
    ReqJson := TStringStream.Create('json content here', TEncoding.UTF8); 
    try 
    IdHTTP1.Request.ContentType := 'application/json'; 
    IdHTTP1.Post(URL, ReqJson); 
    finally 
    ReqJson.Free; 
    end; 
end; 

Чтобы получить JSON, TIdHTTP может либо

  1. вернуть его как String (декодировано с использованием сервера-rep orted кодировок):

    var 
        ReqJson: TStringStream; 
        RespJson: String; 
    begin 
        ReqJson := TStringStream.Create('json content here', TEncoding.UTF8); 
        try 
        IdHTTP1.Request.ContentType := 'application/json'; 
        RespJson := IdHTTP1.Post(URL, ReqJson); 
        finally 
        ReqJson.Free; 
        end; 
        // use RespJson as needed... 
    end; 
    
  2. написать сырые байт на выход TStream по вашему выбору:

    var 
        ReqJson: TStringStream; 
        RespJson: TMemoryStream; 
    begin 
        RespJson := TMemoryStream.Create; 
        try 
        ReqJson := TStringStream.Create('json content here', TEncoding.UTF8); 
        try 
         IdHTTP1.Request.ContentType := 'application/json'; 
         RespJson := IdHTTP1.Post(URL, ReqJson, RespJson); 
        finally 
         ReqJson.Free; 
        end; 
        RespJson.Position := 0; 
        // use RespJson as needed... 
        finally 
        RespJson.Free; 
        end; 
    end; 
    

Код ответа HTTP доступен в свойстве TIdHTTP.Response.ResponseCodeTIdHTTP.ResponseCode).

+0

то, что вы сказали, помогло мне с «первым типом», но у меня все еще есть проблема с «вторым типом», я отредактировал свой вопрос, можете ли вы прочитать его и ответить мне соответственно, спасибо вам большое! –

+0

@AliAhmadi, с чем именно вы столкнулись? Ваше редактирование не делает его более ясным. Что не так сложно помещать содержимое JSON as-is в потомок потомка «TStream», а затем публиковать его? Вы знаете, как производить JSON в первую очередь? –

+0

Что вы подразумеваете под 'производителем JSON', может быть, это моя проблема? (как я уже сказал, я не знаю основ о 'JSON', простого примера было бы более чем достаточно, thx) –