Вызовите метод веб-службы на сервере Flask из JavaScript - PullRequest
1 голос
/ 02 апреля 2019

Я новичок в разработке интерфейсов и разработке веб-сайтов; цель - вызвать метод веб-сервиса на сервере из веб-интерфейса (клиент) .

Context

Я написал веб-сервис Python с Flask и развернул его на своем Raspberry Pi . Я протестировал его с ngrok и почтальоном, и он отлично работает, все методы делают именно то, что должны.
У меня также есть веб-сервер ( Nginx ), работающий на Raspberry .
Веб-сервис Python предоставляется на порт 5000 ; Малина имеет IP 192.168.1.4 .
addWord - это операция POST, предоставляемая моей веб-службой.
Наконец, ПК и Raspberry находятся в одной сети.

Следующий шаг

Я хочу вызвать метод веб-службы Python с веб-сайта внешнего интерфейса, простую HTML-страницу, которую я разместил на своем веб-сервере.

Мой код

Это код моей HTML-страницы:

<head>
  <title>prova insert</title>
</head>

<body>
    <p id='text'></p>
  <script>
        var xhr = new XMLHttpRequest();
        var url = "http://192.168.1.4:5000/addWord";
        xhr.open("POST", url, true);
        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                var json = JSON.parse(xhr.responseText);
                console.log(json.email + ", " + json.password);
                text = document.getElementById("text");
                text.innerHTML = 'Ooooooooooooook';
            }
        };
        var data = JSON.stringify({"ita": "neve", "eng": "snow", "descr": "", "pos":"nome"});
        console.log(data);
        xhr.send(data);
  </script>
</body>

</html>

Код колбы:

from flask import Flask
from flask import request
import json

import db_connection

app = Flask(__name__)


@app.route('/test')
def test():
    return "Test succeeded."

@app.route('/vocaboli')
def get_vocaboli():
    voc = connection.get_all_words()

    return json.dumps(voc)

@app.route('/addWord', methods = ['POST'])
def add_word():
    data = request.get_json()

    print(data)
    print(data.get('ita'))

    ita = data.get('ita')
    eng = data.get('eng')

    descr = data.get('descr') # opzionali
    pos = data.get('pos')

    connection.add_word(ita, eng, descr, pos)

    response = dict(correct='ok')
    return json.dumps(response)


if __name__ == '__main__':
    connection = db_connection.DatabaseConnection()
    app.run()

dbconnection.py:

class DatabaseConnection():
        def __init__(self):
                self.mariadb_connection = mariadb.connect(user=user, password=password, database='vocabulary')
                print('Connection succeeded.')

        def get_cursor(self):
                return self.mariadb_connection.cursor()

        def get_all_words(self):
                cursor = self.get_cursor()

                cursor.execute("select * from vocaboli")
                return cursor.fetchall()

        def add_word(self, ita, eng, descr=None, pos=None):
                cursor = self.get_cursor()
                cursor.execute("insert into vocaboli (ita, eng, description, pos) values ('{}', '{}', '{}', '{}')".format(ita, eng, descr, pos))
                self.mariadb_connection.commit()

        def update_description(self, ita, eng, descr=None):
                cursor = self.get_cursor()
                cursor.execute("update vocaboli set description = '{}' where ita = '{}' and eng = '{}'".format(descr, ita, eng))
                self.mariadb_connection.commit()

выход
enter image description here

Я также пытался сделать POST на http://192.168.1.4/addWord, но он возвращает NOT FOUND.


Вопрос
Как правильно вызвать веб-сервис из кода Javascript? Нужно ли использовать туннель ngrok в качестве URL-адреса или IP-адрес Raspberry?
Нужно ли мне каким-то образом использовать PHP для работы на стороне сервера?
Как я уже сказал, я не знаком с Javascript / PHP, возможно, ответ прост, но я не могу понять это.

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

По умолчанию сервер Flask доступен только локально.Согласно документации Flask , попробуйте указать host='0.0.0.0' при запуске приложения, чтобы сделать его доступным для других устройств в сети:

if __name__ == '__main__':
    connection = db_connection.DatabaseConnection()
    app.run(host='0.0.0.0')

Затем попробуйте отобразить страницу /test избраузер на ПК (http://192.168.1.4:5000/test).

Если это не сработает, убедитесь, что на вашем Raspberry Pi открыт порт 5000.

Отредактируйте адрес ошибки политики CORS:

Попробуйте использовать модуль flask_cors , чтобы разрешить CORS:

from flask import Flask
from flask_cors import CORS

...

app = Flask(__name__)
CORS(app)

...
0 голосов
/ 02 апреля 2019

Здесь я вижу пару вещей:

  1. Если вы используете Nginx, создайте апстрим для http://localhost:5000, чтобы он мог действовать как обратный прокси-сервер, а приложения доступны наhttp://192.168.1.4 при использовании ssl это будет https://192.168.1.4

  2. Если бэкэнд и внешний интерфейс работают на разных серверах, вам необходимо использовать CORS, это может быть Ngnix / Flask уровень в зависимости от того, как вы настроили.

  3. Вы должны указать колбу, а не функцию, что вы будете работать с типом содержимого JSON для этого видана ссылка

Эти шаги помогут решить вашу проблему.Ничего общего с БД, если она работает с почтальоном.

...