【问题标题】:Why do I need to removeChild form input to call custom GAE API为什么我需要 removeChild 表单输入才能调用自定义 GAE API
【发布时间】:2016-07-18 23:28:47
【问题描述】:

我要做的就是将一个字符串传递给一个愚蠢的简单 GAE 端点 API,它只返回我发送的内容。出于学习目的,我想在不使用 Google Javascript 库或 Jinja、Flask、Webapp2 等的情况下做到这一点。OBTW,是的,我知道 API Explorer。那里的请求显然很简单,这让我想知道如何在不使用 API Explorer 的情况下完成它。

下面的代码不是很好,它只是用于检查 API。 (是的,我从 Google Tac-Tac-Toe 示例开始)

在我的 Javascript 中,您会看到 form1.removeChild(input1)。在尝试使用<input type=text> 中的值构建查询字符串后;我发现从表单中删除子元素(<input type=text>)可以让它像基本的静态 URL(这是下面 HTML 中的第二个表单元素)一样工作。

如果子输入元素没有被删除,我会在本地 dev GAE 服务器上收到以下错误。

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 384, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

查看 Chrome 开发人员工具上的请求标头,我发现两种表单的标头相同。不同之处在于第一个具有 Form-Data 而第二个没有。两者都有一个查询字符串。

我有两个问题: 有没有办法设置 Endpoints API 来处理没有 GAE JS 库的表单数据?

仅使用 JS,还有另一种更清洁的方法吗?意思是,不需要删除表单数据。

GAE Javascript 库是正确的方法,我明白了。同样,我只是想确保我了解这里的基础知识。

这是 API(Python):

import endpoints
from protorpc import remote, messages

CLIENT_ID = '[from the developer console]'

class StubMessageIn(messages.Message):
   tell_me = messages.StringField(1)

@endpoints.api(name='tictactoe',
           version='v1',
           allowed_client_ids=[CLIENT_ID],
           audiences=[CLIENT_ID])
class TicTacToeApi(remote.Service):

@endpoints.method(request_message=StubMessageIn,
                  response_message=StubMessageIn,
                  path='stub2',
                  name='stub_method_2',
                  http_method='POST')
def stub_it2(self, request):
    return request

APPLICATION = endpoints.api_server([TicTacToeApi],
                               restricted=False)

这是 HTML 和 JS:

<body>
<script>
    function do_it() {
        var form1 = document.getElementById('f1');
        var input1 = document.getElementById("tell_me");
        var data1 = input1.value;
        var data2 = "?tell_me=" + data1 ;
        var url1 = "http://localhost:16080/_ah/api/tictactoe/v1/stub2";
        console.log("Going to: " + url1 + data2);
        form1.method = "POST";
        form1.action = url1 + data2;
        form1.removeChild(input1)
        form1.submit()
        return false;
    }
</script>

<form onsubmit="do_it();"
    name = f1
    id = f1>
    <input type='text' name = 'tell_me' id = 'tell_me'>
    <input type='submit' value = "Submit -w- JS">
</form>

<form method="POST"
    action = "http://localhost:16080/_ah/api/tictactoe/v1/stub2?tell_me=thursday" >
    <input type="submit" value = "Submit no JS">
</form>
</body>

这里是 app.yaml:

application: fsndp4-tic-tac-toe-01
version: 1
runtime: python27
threadsafe: true
api_version: 1

handlers:
# Static assets
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico
- url: /js
  static_dir: static/js
- url: /css
  static_dir: static/css
- url: /images
  static_dir: static/images

- url: /
  static_files: templates/index.html
  upload: templates/index\.html
  secure: always

# Endpoints handler
- url: /_ah/spi/.*
  script: tictactoe_api.APPLICATION
  http_headers:
    Access-Control-Allow-Origins: *

libraries:
- name: pycrypto
  version: latest

- name: endpoints
  version: 1.0

这是在 Chrome 中呈现的 HTML 的样子

这是一切正常时的响应;假设您将“Ham and Eggs”放入文本输入:

{
 "tell_me": "Ham and Eggs"
}

我希望这比泥浆更清楚一点......提前谢谢......

【问题讨论】:

    标签: javascript python html forms google-app-engine


    【解决方案1】:

    睡觉有帮助...第二个问题的一个答案是将文本输入移到表单之外。这是新的 HTML:

    <body>
            <script>
                function do_it() {
                    var form1 = document.getElementById('f1');
                    var input1 = document.getElementById("tell_me");
                    var data1 = input1.value;
                    var data2 = "?tell_me=" + data1 ;
                    var url1 = "http://localhost:16080/_ah/api/tictactoe/v1/stub2";
                    console.log("Going to: " + url1 + data2);
                    form1.method = "POST";
                    form1.action = url1 + data2;
                    // form1.removeChild(input1)
                    form1.submit()
                    return false;
                }
            </script>
            <!--
            Move tell_me text input out of the form so it does not
            need to be removed prior to submitting the form.
            Formatting can be solved with an HTML table later
             -->
    
            <input type='text' name = 'tell_me' id = 'tell_me'>
    
            <form onsubmit="do_it();"
                  name = f1
                  id = f1>
                <input type='submit' value = "Submit -w- JS">
            </form>
    
    
            <form method="POST"
                    action = "http://localhost:16080/_ah/api/tictactoe/v1/stub2?tell_me=thursday" >
                <input type="submit" value = "Submit no JS">
            </form>
    </body>
    

    请注意,我只是注释掉了form1.removeChild(input1),以使两个示例之间更加清晰。

    这为我想做的事情清理了足够的东西。我正在考虑这个答案。当然,任何关于 Endpoint API 如何工作的额外信息都会受到赞赏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-01
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 2013-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多