首页 > 解决方案 > flutter http get - 为什么我在访问 NodeMCU 上运行的服务器时会收到“无效的请求方法”?

问题描述

当我尝试从 Flutter 应用程序向运行在 NodeMCU(带 Lua 的微控制器)上的服务器发出请求时,出现以下错误:

E/flutter (11080): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter (11080): Invalid request method
E/flutter (11080): #0      IOClient.send (package:http/src/io_client.dart:64:7)
E/flutter (11080): <asynchronous suspension>
E/flutter (11080): #1      BaseClient._sendUnstreamed (package:http/src/base_client.dart:171:38)
E/flutter (11080): <asynchronous suspension>
E/flutter (11080): #2      BaseClient.get (package:http/src/base_client.dart:34:5)
E/flutter (11080): #3      get.<anonymous closure> (package:http/http.dart:47:34)
E/flutter (11080): #4      _withClient (package:http/http.dart:167:20)
E/flutter (11080): <asynchronous suspension>
E/flutter (11080): #5      get (package:http/http.dart:47:3)
E/flutter (11080): #6      _MyHomePageState._sendGet1 (file:///D:/dev/repos/github/thing_client/lib/main.dart:62:33)
E/flutter (11080): <asynchronous suspension>
E/flutter (11080): #7      _MyHomePageState.build.<anonymous closure> (file:///D:/dev/repos/github/thing_client/lib/main.dart:137:17)
E/flutter (11080): #8      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:494:14)
E/flutter (11080): #9      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:549:30)
E/flutter (11080): #10     GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
E/flutter (11080): #11     TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:161:9)
E/flutter (11080): #12     TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:94:7)
E/flutter (11080): #13     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:315:9)
E/flutter (11080): #14     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:73:12)
E/flutter (11080): #15     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:11)
E/flutter (11080): #16     _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:143:19)
E/flutter (11080): #17     _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:121:22)
E/flutter (11080): #18     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:101:7)
E/flutter (11080): #19     _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:64:7)
E/flutter (11080): #20     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:48:7)
E/flutter (11080): #21     _invoke1 (dart:ui/hooks.dart:134:13)
E/flutter (11080): #22     _dispatchPointerDataPacket (dart:ui/hooks.dart:91:5)

发生这种情况的行是:

final response = await http.get('http://192.168.1.94', headers: {"Accept": "*/*"},);

“接受”标题没有区别。
相反,如果我将它定向到任何其他 URL(例如“ https://httpbin.org/get ”),则请求将正确执行:

I/flutter (15857): {
I/flutter (15857):   "args": {}, 
I/flutter (15857):   "headers": {
I/flutter (15857):     "Accept": "*/*", 
I/flutter (15857):     "Accept-Encoding": "gzip", 
I/flutter (15857):     "Connection": "close", 
I/flutter (15857):     "Host": "httpbin.org", 
I/flutter (15857):     "User-Agent": "Dart/2.0 (dart:io)"
I/flutter (15857):   }, 
I/flutter (15857):   "origin": "89.69.232.252", 
I/flutter (15857):   "url": "https://httpbin.org/get"
I/flutter (15857): }

在 CURL 中尝试相同的请求对两者都有效:

$ curl -X GET "https://httpbin.org/get" -H  "Accept-Encoding: gzip" -H  "User-Agent: Dart/2.0 (dart:io)" -H  "Connection: close"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                 Dload  Upload   Total   Spent    Left  Speed
100   254  100   254    0     0     96      0  0:00:02  0:00:02 --:--:--    96{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip",
    "Connection": "close",
    "Host": "httpbin.org",
    "User-Agent": "Dart/2.0 (dart:io)"
  },
  "origin": "89.69.232.252",
  "url": "https://httpbin.org/get"
}

$ curl -X GET "http://192.168.1.94" -H  "Accept-Encoding: gzip" -H  "User-Agent: Dart/2.0 (dart:io)" -H  "Connection: close"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                 Dload  Upload   Total   Spent    Left  Speed
100    11    0    11    0     0     47      0 --:--:-- --:--:-- --:--:--    47{"empty":1}

运行服务器的lua代码是:

function serve(conn, payload)
    conn:send("{\"empty\":1}")
    conn:close()
end

srv=net.createServer(net.TCP)
srv:listen(80, function(conn)
    conn:on("receive",function(conn,payload)
        serve(conn, payload)
        collectgarbage()
    end) 
end)

服务器对我来说一直运行良好(在 curl、wget 和浏览器中),Flutter 中的 get 请求在其他服务器上运行良好。只有两者结合才有问题。http包
版本为0.11.3+17

[编辑]更多信息:
测试是在搭载 Android 4.1.18 的华为 P9 Lite 手机上完成的。
Flutter 构建环境(带 Android Studio)已完全更新。
在笔记本电脑上进行 CURL 测试,也在笔记本电脑和手机上的浏览器中进行了测试。
所有设备(笔记本电脑、电话、服务器主板)都是同一路由器的直接客户端,具有静态 IP。

标签: httpdartflutter

解决方案


归功于@augustzf(请参阅有问题的评论):

当 Flutter 没有得到正确的 HTTP 响应时会发生恐慌,因此需要发送 lua 代码,例如:

conn:send("HTTP/1.0 200/OK\r\nServer: tiny lua webserver\r\n")

推荐阅读