通过javascript

时间:2019-04-02 18:00:46

标签: javascript python web-services flask web-frontend

我是前端开发和网站开发的新手;目标是从Web界面(客户端)上调用服务器上的Web服务方法

上下文

我用Flask编写了一个Python Web服务,并将其部署在我的 Raspberry Pi 上。我用ngrok和Postman对其进行了测试,并且效果很好,所有方法都完全达到了它们的要求。
我还在Raspberry上运行了一个Web服务器( Nginx ) 。
Python Web服务在端口5000 上公开; Raspberry具有 IP 192.168.1.4
addWord 是通过Web服务提供的POST操作。
最后,PC和Raspberry在同一网络上。

下一步

我想从放置在Web服务器上的前端网站(一个简单的HTML页面)调用Python Web服务的方法。

我的代码

这是我的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

我也尝试对POSThttp://192.168.1.4/addWord,但是它返回了NOT FOUND


问题
如何以正确的方式从Javascript代码调用Web服务?我需要使用ngrok隧道作为URL,还是必须使用Raspberry的IP?
我是否可以通过某种方式使用 PHP 在服务器端工作?
就像我说的那样,我对Javascript / PHP并不熟悉,答案可能是直截了当的,但我无法弄清楚。

2 个答案:

答案 0 :(得分:2)

默认情况下,只能在本地访问Flask服务器。根据{{​​3}},请在运行应用时尝试指定host='0.0.0.0',以使其可从网络中的其他设备进行访问:

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

然后尝试通过PC(Flask documentation)上的浏览器显示/test页面。

如果这不能解决问题,请确保在Raspberry Pi上打开端口5000。

编辑以解决CORS政策错误:

尝试使用http://192.168.1.4:5000/test模块来启用CORS:

from flask import Flask
from flask_cors import CORS

...

app = Flask(__name__)
CORS(app)

...

答案 1 :(得分:0)

我在这里看到几件事:

  1. 如果您使用的是Nginx,则为http://localhost:5000创建一个上游,以便它可以充当反向代理,并且http://192.168.1.4上的应用程序可以通过ssl获得https://192.168.1.4

  2. 如果后端和前端在不同的服务器上运行,则需要使用CORS,取决于您的配置方式,它可能处于Ngnix / Flask级别。

  3. 对于link

  4. ,您需要告诉flask而不是要使用JSON内容类型的函数。

这些步骤将对您的问题进行排序。如果数据库可以与Postman一起使用,则与数据库无关。