我已经将 Nginx 设置为我的 django 后端 api 的反向代理。来自 Postman 的请求工作得很好,但在 Flutter 上,我在执行 GET 请求时从 nginx 服务器收到 HTTP 400 157。
检查日志后,我看到以下内容:
client sent invalid header line: "\x3a..." while reading client request headers
这是我的 nginx.conf。
worker_processes auto;
events {
worker_connections 1024;
}
http {
log_format custom '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" $request_time';
#Note that these are defined outside of the server block altho they don't necessarily need to be
proxy_cache_path /tmp/nginx levels=1:2 keys_zone=my_zone:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
default_type application/octet-stream;
include /etc/nginx/mime.types;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
upstream my-django-rest-api {
server 172.16.16.1:8080; # The internal Django API service
}
server {
listen 1652;
# Access & Error Logs
access_log /var/log/nginx/access.log custom;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://my-django-rest-api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache my_zone;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_buffering on;
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 1m;
# WebSocket support (nginx 1.4)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
开始故障排除之前,我需要在 Nginx 端做什么 来自前端?
标题行中被称为“无效”的“\x3a...”到底是什么?
除上述内容之外,我还添加了为每个 Postman 发送的标头,并针对同一 GET 请求进行 flutter 发送:
GET 请求的 Postman 标头
Key Value
Host <calculated when request is sent>
User-Agent PostmanRuntime/7.42
Accept */*
Accept Encoding gzip,deflate,br
Connection keep-alive
Authorization Token f384996c63b4****************
发送请求时 Flutter 端功能
Future<HttpieResponse> get(url,
{Map<String, String>? headers,
Map<String, dynamic>? queryParameters,
bool? appendLanguageHeader,
bool? appendAuthorizationToken}) async {
var finalHeaders = _getHeadersWithConfig(
headers: headers,
appendLanguageHeader: appendLanguageHeader,
appendAuthorizationToken: appendAuthorizationToken);
if (queryParameters != null && queryParameters.keys.isNotEmpty) {
url = url + _makeQueryString(queryParameters);
}
Response? response;
try {
response = await client.get(Uri.parse(url), headers: finalHeaders);
} catch (error) {
_handleRequestError(error);
}
if (response != null) {
return HttpieResponse(response);
}
throw ();
}
Map<String, String> _getHeadersWithConfig(
{Map<String, String>? headers = const {},
bool? appendLanguageHeader,
bool? appendAuthorizationToken}) {
headers = headers ?? {};
Map<String, String> finalHeaders = Map.from(headers);
appendLanguageHeader = appendLanguageHeader ?? true;
appendAuthorizationToken = appendAuthorizationToken ?? false;
if (appendLanguageHeader) finalHeaders['Accept-Language'] = _getLanguage();
if (appendAuthorizationToken && authorizationToken != null) {
finalHeaders['Authorization'] = 'Token $authorizationToken';
}
if (magicHeaderName != null && magicHeaderValue != null) {
finalHeaders[magicHeaderName!] = magicHeaderValue!;
}
return finalHeaders;
}
String _getLanguage() {
return _localizationService.getLocale().languageCode.toLowerCase();
}
.env.json
{
"API_URL": "http://24.XX.XX.XX:70/",
"MAGIC_HEADER_NAME": "",
"MAGIC_HEADER_VALUE": "",
}
\x3a 是分号的 Ascii 代码。我怀疑 headers 数组以某种方式在 header 键中包含了分号,这是不允许的。您只能将其放入值中。