我有一个 HTTP(S) GET 请求,该请求在 java(Android sdk)和 Python 中运行良好,但是当我尝试将其移植到 flutter 时,它返回一个空字符串。 它应该返回一个 JSON,其中包含大约 2MB 的数据。
这是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 代码,它们有望支持区分大小写的 header 。 呵呵,这一切都是因为他们无法将大写“K”更改为小写“k”。
最佳答案
对于任何 HTTP 请求,最好测试 HTTP 响应代码。在您的情况下,您将收到 403 Forbidden
,因此您的凭据或 API key 不会被服务器接受。
在第一种方法中,您实际上向服务器发送两个请求 - 每个等待一个。考虑更改为:
http.Response r = await fetchPost();
print(r.statusCode);
print(r.body.length);
编辑 - 服务器未接受您的 API key ,服务器的行为方式不符合标准。
Dart HttpClient(在第二种方法中直接使用,在第一种方法中间接使用)恰好将所有请求 header 小写。这是完全有效的,因为 RFC 7230 规定“每个 header 字段都包含一个不区分大小写的字段名称,后跟冒号(“:”)、可选的前导空格、字段值和可选的尾随空白。".
因此,即使您添加 header "apiKey": "7856d...
,网络上发出的仍是 apikey: 7856d...
但是(这是您不喜欢的一点),HTTP 服务器似乎是非标准的,不会接受 apikey
而不是 apiKey
。尝试更改 Python 代码以使用 apikey
或 APIKEY
,您会得到 403。
(请注意,HTTPS 没有区别,使用 HTTP 会得到相同的结果。)
看来您需要将此作为错误报告给 Kreta。
关于android - Flutter 返回空字符串 - HTTP(S) GET 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50199711/