Задать вопрос

Почему при отправке POST-запроса к серверу я получаю ошибку 404?

Моя задача - это отправить к серверу запрос с двумя параметрами login и password и распарсить ответ в JSON-формате, который он мне вернёт.

У меня есть самописный скрипт запущенный на сервере:
import sqlite3
from flask import Flask, jsonify, request, abort
import json

app = Flask('__name__')

def register(login, password, data=""):
    insert_data = (login, password, data)
    conn = sqlite3.connect("users.db")
    cursor = conn.cursor()

    x = cursor.execute(" SELECT * FROM users WHERE login=?", (login,)).fetchall()

    if not x:
        cursor.execute("INSERT INTO users VALUES (?,?,?)", insert_data)
        conn.commit()
        return "OK"
    return "Username is registered"

def login(login, password):
    insert_data = (login, password)
    conn = sqlite3.connect("users.db")
    cursor = conn.cursor()

    x = cursor.execute(" SELECT data FROM users WHERE login=? AND password=?", (login,password)).fetchone()

    if not x:
        return "Login or password is incorrect"
    return {"status": "logged in", "data": x[0]}

def delete(login, password):
    insert_data = (login, password)
    conn = sqlite3.connect("users.db")
    cursor = conn.cursor()

    x = cursor.execute(" SELECT data FROM users WHERE login=? AND password=?", (login,password)).fetchone()

    if not x:
        return "Login or password is incorrect"
    x = cursor.execute(" DELETE FROM users WHERE login=? AND password=?", (login,password)).fetchone()
    conn.commit()
    return "user deleted"

#=======================================================================================

@app.route('/register', methods=['POST'])
def write_reg():
    if not request.json:
        print(request.json)
        abort(404)

    user = {"login": request.json["login"],
              "password": request.json["password"],
              "data": request.json.get("data") or ""}
    return register(**user), 201

@app.route('/login', methods=['POST'])
def write_log():
    if not request.json:
        print(request.json)
        abort(404)

    user = {"login": request.json["login"],
              "password": request.json["password"]}
    return login(**user), 201

@app.route('/delete', methods=['POST'])
def write_del():
    if not request.json:
        print(request.json)
        abort(404)

    user = {"login": request.json["login"],
              "password": request.json["password"]}
    return delete(**user), 201

@app.errorhandler(404)
def not_found(error):
    return jsonify({'error': 'Not enought data'}), 404

if __name__ == '__main__':
    app.run(host='0.0.0.0',debug=True, threaded=True, port=5123)


POST-запрос отправляю вот таким образом:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + "?" + Data);

request.Method = "POST";
request.Accept = "application/json";
request.UserAgent = "Mozilla/5.0....";

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
StringBuilder output = new StringBuilder();
output.Append(reader.ReadToEnd());
response.Close();


И получаю ошибку 404:
System.Net.WebException: "Удаленный сервер возвратил ошибку: (404) Не найден."


Подскажите, в чём дело? При отправке аналогичного запроса через консоль с помощью httpie всё проходит нормально и ответ возвращается:
HTTP/1.0 201 CREATED
Content-Length: 43
Content-Type: application/json
Date: Mon, 07 Sep 2020 09:49:10 GMT
Server: Werkzeug/0.16.0 Python/3.7.7

{
    "data": "",
    "status": "logged in"
}
  • Вопрос задан
  • 2513 просмотров
Подписаться 2 Простой 2 комментария
Решения вопроса 2
404 кидается на
if not request.json:
        print(request.json)
        abort(404)

Опустим вопрос, а почему тут кидается 404, хотя по смыслу должен быть 400.
А чтобы не кидалось 404 надо добавить json-тело запросу примерно так:
var httpClient = new HttpClient();
var request = new
{
	login = "admin",
	password = "12345"
};
var jsonString = JsonSerializer.Serialize(request);
var response = await httpClient.PostAsync(url, new StringContent(jsonString))
var contentString = await response.Content.ReadAsStringAsync();
var result = JsonDocument.Parse(contentString);
Ответ написан
@val_gr Автор вопроса
string result;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(URL);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
    string json = new JavaScriptSerializer().Serialize(new
    {
        login = "demo_login",
        password = "demo_pass"
    });

    streamWriter.Write(json);
}

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    result = streamReader.ReadToEnd();
}
JObject jObj = JObject.Parse(result);

var response = jObj["status"].ToString();
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@cicatrix
было бы большой ошибкой думать
Вообще для POST запроса надо бы RequestStream заполнить собственно, данными JSON. Вы отправляете пустой запрос.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы