Я переносил приложение веб-сервера с PHP на Python Flask. Я пытаюсь отправить запрос POST с Unity C# на Python Flask сервер. Однако я получаю ошибки. Первоначально код Unity был от использования PHP сервера, который работал нормально.
Оригинальный php серверный код, который работал нормально.
$input = file_get_contents("php://input");
$input_decoded = json_decode($input, true);
if (isset($input_decoded["data"])) {
processMessage($input_decoded);
}
Я пробовал несколько вещей.
- Если я заменил ключ в Unity на что-то другое (например, data2), ошибка в Flask по-прежнему говорит о данных Key error.
Код Unity
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add(new MultipartFormDataSection("data=" + query));
UnityWebRequest www = UnityWebRequest.Post("http://example.com:5000/path/", formData);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
Код сервера
from flask import Flask, request
app = Flask(__name__)
@app.route('/path/', methods=['POST'])
def show_subpath():
data = request.form['data']
return data
Flask ошибка:
123.456.789.012 - - [24/Apr/2020 03:49:54] "POST /path/ HTTP/1.1" 500 -
Traceback (most recent call last):
File "/opt/anaconda3/lib/python3.7/site-packages/flask/app.py", line 2463, in __call__
return self.wsgi_app(environ, start_response)
File "/opt/anaconda3/lib/python3.7/site-packages/flask/app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "/opt/anaconda3/lib/python3.7/site-packages/flask/app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "/opt/anaconda3/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/opt/anaconda3/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/opt/anaconda3/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/opt/anaconda3/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/opt/anaconda3/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/opt/anaconda3/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/opt/anaconda3/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/jupyter/example_flask/byebye.py", line 7, in show_subpath
data = request.form['data']
File "/opt/anaconda3/lib/python3.7/site-packages/werkzeug/datastructures.py", line 443, in __getitem__
raise exceptions.BadRequestKeyError(key)
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'data'
123.456.789.012 - - [24/Apr/2020 03:50:28] "POST /path/ HTTP/1.1" 500 -
Ошибка Unity:
HTTP/1.1 500 Internal Server Error
UnityEngine.Debug:Log(Object)
FrostweepGames.Plugins.GoogleCloud.SpeechRecognition.Examples.<doSpeach>d__9:MoveNext() (at Assets/scripts/player.cs:54)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
Как это исправить, чтобы я мог отправить свой POST запрос?
Редактировать: я уверен, но думаю, что, возможно, существуют различные типы запросов POST, поэтому это не так легко работает? Как, может быть, составной POST - это не то, что Flask использует?
Редактировать 2: я мог бы использовать python для отправки запроса POST следующим образом, и он отлично работает. (Но код Unity имеет ошибку, как указано выше)
import requests
r = requests.post("http://example.com:5000/path/", data={'data': 'hi'})
print(r.text) # prints "hi"
Редактировать 3: При отладке я обнаружил, что сервер Flask получал пустую строку b''
, когда я печатаю request.data
(веб-сервер получил запрос с пустым телом), поэтому он не мог найти значение для ключа data
.
Редактировать 4: я пытался добавить
www.chunkedTransfer = false;
www.useHttpContinue = false;
к коду Unity прямо перед yield
на основе советы на форумах единства но это не сработало. Запрос был по-прежнему пустым.
Редактировать 5: предыдущий рабочий код был подключен к серверу https PHP, а новый код - к серверу http. Переход с https на http, возможно, повлиял на него, основываясь на post 17 на этой странице форумов Unity.
Редактировать 6: Я был не прав. Запрос не пустой.
request.data # is b''
request.form` # is ImmutableMultiDict([(None, 'data=co')])
Я предположил, что request.data
печатал все данные в запросе, и поскольку он был пустым, я предположил, что запрос был пустым. Но request.form
фактически имел информацию о запросе. В этом случае строка запроса была 'co'.