在 javascript 中简单地获取 GET 请求到烧瓶服务器

2022-01-20 00:00:00 python api flask fetch javascript

我正在尝试将一些 json 数据从烧瓶服务器显示到我的 html 页面,但是在尝试获取资源时出现 TypeError: NetworkError. 带有 Promise { <state>: "被拒绝" }.

I'm trying to display some json data from a flask server to my html page but I have a TypeError: NetworkError when attempting to fetch resource. with a Promise { <state>: "rejected" }.

server.py

from flask import Flask, request, jsonify

app = Flask(__name__)


@app.route('/hello', methods=['GET'])
def hello():
    jsonResp = {'jack': 4098, 'sape': 4139}
    print(jsonify(jsonResp))
    return jsonify(jsonResp)

if __name__ == '__main__':
    app.run(host='localhost', port=8989)

script.js

function getHello() {
    const url = 'http://localhost:8989/hello'
    const response = fetch(url)
    console.log(response);
    document.getElementById("demo").innerHTML = response;
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <button onclick="getHello()">click</button>
    <label id="demo"></label>

    <script src="script.js"></script>
</body>
</html>

当我单击按钮时,标签部分中还有一个 [object Promise].

I also have a [object Promise] in the label section when I click on the button.

我做了最简单的代码,但它不起作用.

I did the simplest code possible but it doesn't work.

推荐答案

这可能是同源策略造成的.浏览器不允许调用不同的来源,除非服务器设置了特殊的 HTTP 标头.如果您从浏览器打开此 html 文件,则服务器的来源 localhost 与浏览器中的来源不匹配,这可能是文件路径.您可以通过将 Access-Control-Allow-Origin 标头添加到响应中来使其工作,如下所示:

This could be caused by Same-Origin Policy. Browser does not allow making calls to different origin unless server sets special HTTP header. If you are opening this html file from your browser, the origin of server which is localhost does not match with the origin in your browser which is probably a file path. You can make it work by adding Access-Control-Allow-Origin header to the response as follows:

from flask import after_this_request

@app.route('/hello', methods=['GET'])
def hello():
    @after_this_request
    def add_header(response):
        response.headers['Access-Control-Allow-Origin'] = '*'
        return response

    jsonResp = {'jack': 4098, 'sape': 4139}
    print(jsonify(jsonResp))
    return jsonify(jsonResp)

现在没有网络错误,但你的承诺正在等待,所以你需要为它添加 then.

Now there is no network error but your promise is pending so you need to add then for it.

或者,您可以通过 Flask 服务器提供 index.html 文件,以便来源匹配.

Alternatively you can serve index.html file by your Flask server so that origins match.

您可以在此处阅读有关 CORS 和 SOP 的更多信息:

You can read more about CORS and SOP here:

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

相关文章