【问题标题】:Can't use Javascript fetch against App Engine behind Users API无法在用户 API 后面对 App Engine 使用 Javascript 获取
【发布时间】:2017-02-01 20:30:34
【问题描述】:

我有一个只有 App Engine 项目管理员才能访问的 Flask 应用,方法是使用以下 app.yaml

version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /.*
  script: app.py
  secure: always
  login: admin

在我的应用程序中,我有一个简单地返回一些 JSON 的端点:

@app.route('/api/v1/data')
def api():
    return jsonify(data)

在我的前端,我试图在 Javascript 中获取 JSON 数据(当我运行“普通”烧瓶服务器时它工作得非常好):

fetch('/api/v1/data')
.then(function (response) {
    console.log(response)
    return response.json();
  }).then(function (myData) {
    doSomethingWithData(myData);
  });

但是,我无法获取数据。使用本地服务器,我收到以下错误:

(index):1 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

响应似乎说我没有登录,并在控制台日志中给了我一个 url(注意:我没有在任何地方添加任何类型的回调,我认为这来自用户 API):

http://127.0.0.1:5000/_ah/login?continue=http%3A//127.0.0.1%3A5000/api/v1/data

在部署的应用程序上我得到:

Fetch API cannot load https://www.google.com/accounts/ServiceLogin?service=ah&passive=true&contin....
Redirect from 'https://www.google.com/accounts/ServiceLogin?service=ah&passive=true&contin...'
to 'https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=...'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the
requested resource. Origin 'https://....appspot.com' is therefore not allowed access.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the
resource with CORS disabled.

我尝试将 CORS 添加到 fetch 调用和烧瓶响应中,但没有任何成功。谷歌搜索时也找不到任何相关信息,因此非常感谢您的帮助!

【问题讨论】:

  • 如果你只是导航到 api url 你能看到数据吗?
  • @dandavis 是的,效果很好。在本地和部署的应用程序中。

标签: javascript python json google-app-engine


【解决方案1】:

我在调试后发现了问题。

默认情况下,Javascript 获取 API 不发送 cookie。由于 Google App Engine 的用户 API 使用 cookie 进行登录会话,因此 fetch 发出的请求似乎未经身份验证。要将 cookie 与请求一起发送,您必须将带有“same-origin”的 request credentials 添加到 fetch 调用中:

fetch('/api/v1/data', { credentials: 'same-origin' })

【讨论】:

    【解决方案2】:

    “<html...

    您没有在函数中定义data,所以这可能是问题所在。你能给我们看看那个代码吗?

    @app.route('/api/v1/data')
    def api():
        data = ....
        return jsonify(data)
    

    并且,该 url 的回调将没有管理员权限,因此 login: admin 不能在那里使用。试试:

    handlers:
    - url: /api/v1/data
      script: app.py
      #secure: always # if you use this, make sure you specify an https callback url: http://127.0.0.1:5000/_ah/login?continue=https%3A//127.0.0.1%3A5000/api/v1/data (when deployed with production url)
    
    - url: /.*
      script: app.py
      secure: always
      login: admin
    

    然后,continue=https%3A//127.0.0.1%3A5000/api/v1/data 无法通过 Google API 工作,因为他们无法访问您的本地开发服务器。

    【讨论】:

    • 我刚刚注释掉了我的真实数据。但是那里的数据有效。如果我只运行烧瓶服务器,则 fetch 调用按预期工作。此外,如果我导航到本地或部署的应用程序中的 API 端点,它会向我显示 JSON 数据。
    • 回调URL不是我加的。当我在本地运行它时,它只是“到达”那里。
    猜你喜欢
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多