Flutter возвращает пустую строку - HTTP (S) GET запрос - PullRequest
0 голосов
/ 06 мая 2018

У меня есть запрос HTTP (S) GET, который отлично работает в Java (Android SDK) и Python, но когда я попытался портировать его, чтобы трепетать, он возвращает пустую строку. Он должен вернуть JSON с ~ 2 МБ данных в нем.

Вот код Python:

import http.client

HOST, PORT = 'kretaglobalmobileapi.ekreta.hu', 443
headers = {"apiKey": "7856d350-1fda-45f5-822d-e1a2f3f1acf0", "Connection": "keep-alive",
           "Accept": "application/json", "HOST": "kretaglobalmobileapi.ekreta.hu"}

conn = http.client.HTTPSConnection(host=HOST, port=PORT)
conn.request("GET", "/api/v1/Institute", headers=headers)

response = conn.getresponse()

data = response.read()
print(data)

conn.close()

Я испробовал два разных подхода к версии Flutter, но ни один из них не сработал.

Первый подход:

import 'dart:async';
import 'dart:convert' show utf8, json;
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<http.Response> fetchPost() {
  return http.get(
    "https://kretaglobalmobileapi.ekreta.hu/api/v1/Institute",
    // Send authorization headers to your backend
      headers : {"apiKey": "7856d350-1fda-45f5-822d-e1a2f3f1acf0", "Connection": "keep-alive",
        "Accept": "application/json", "HOST": "kretaglobalmobileapi.ekreta.hu"}
  );
}

void login() async {

  print((await fetchPost()).body);
  print((await fetchPost()).body.length);

}

Возвращает:

Performing full restart...
Restarted app in 3,648ms.
I/flutter (18739): 
I/flutter (18739): 0

Второе:

Future<Map<String, dynamic>> getInstitutes(HttpClient client) async {
  final String url = "https://kretaglobalmobileapi.ekreta.hu/api/v1/Institute";

  final HttpClientRequest request = await client.getUrl(Uri.parse(url))
    ..headers.add("Accept", "application/json")
    ..headers.add("HOST", "kretaglobalmobileapi.ekreta.hu")
    ..headers.add("apiKey", "7856d350-1fda-45f5-822d-e1a2f3f1acf0")
    ..headers.add("Connection", "keep-alive");

  final HttpClientResponse response = await request.close();
  print(json.decode(await response.join()));

  return json.decode(await response.transform(utf8.decoder).join());
}

Я опускаю здесь GUI и стандартный код, полный код на pastebin .

Обновление: проблема заключалась в том, что API, к которому я подключался, использовал устаревшие HTTP-стандарты. Я сказал об этом службе поддержки, они сказали, что не хотят это исправлять, поэтому мне придется создать новый веб-сервер (возможно, на Python), который будет работать между клиентом и API. Другой вариант - использовать собственный код Android и iOS, который, как мы надеемся, будет поддерживать заголовки с учетом регистра. Да, вся эта суета в том, что они не могут изменить прописную букву «K» на строчную «k».

1 Ответ

0 голосов
/ 06 мая 2018

Для любого HTTP-запроса рекомендуется проверить код ответа HTTP. В вашем случае вы получаете 403 Forbidden, поэтому ваши учетные данные или ключ API не принимаются сервером.

При первом подходе вы фактически отправляете на сервер два запроса - по одному на каждое ожидание. Рассмотрите возможность изменения на:

  http.Response r = await fetchPost();
  print(r.statusCode);
  print(r.body.length);

РЕДАКТИРОВАТЬ - Это ваш ключ API , который не принимается сервером, который ведет себя нестандартным образом.

Dart HttpClient (который используется непосредственно во втором подходе и косвенно в первом) происходит со строчными буквами всех заголовков запросов. Это совершенно верно, потому что RFC 7230 заявляет " Каждое поле заголовка состоит из имени поля без учета регистра , за которым следует двоеточие (": "), необязательный начальный пробел, значение поля и необязательный трейлинг пробельные. ».

Итак, даже если вы добавляете заголовок "apiKey": "7856d..., то, что выходит на провод, это apikey: 7856d...

Но, (и этот бит вам не понравится), похоже, что HTTP-сервер нестандартен и не будет принимать apikey вместо apiKey. Попробуйте изменить код Python на apikey или APIKEY, и вы получите 403.

(Обратите внимание, что HTTPS не имеет значения, вы получаете те же результаты с HTTP.)

Похоже, вы должны сообщить об этом как об ошибке Крете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...