【问题标题】:Flask - Getting JavaScript and Python to CommunicateFlask - 让 JavaScript 和 Python 进行通信
【发布时间】:2015-06-15 17:07:27
【问题描述】:

我正在使用 Flask Python 框架构建一个相当简单的 CRM。我有一个我们有兴趣联系的公司的数据库。用户首先输入他们想联系多少家公司。然后用户被重定向到这个页面:

基本上对于此页面上的每一行/公司,用户将单击联系或不联系单选按钮。

我想要完成的事情

一旦用户点击底部的“让魔法发生”按钮,JavaScript 就会遍历每一行并查看点击了哪个按钮。然后,它将数据库唯一 ID 附加到两个数组之一,“contact”和“remove”。然后这些信息通过 getJSON 传递给 python,python 使用 request.args.get 捕获 json 数据。

最后,Python 做了两件事之一:

  • 对于删除数组中的公司,它会更改相应数据库实例中的布尔值
  • 对于联系人数组中的公司,它运行一个单独的函数,该函数使用 SMTP 向该公司发送电子邮件

我挂断电话的地方

我似乎无法在 Python 中检索 json 数据,我现在正在尝试做一个简单的打印语句来表明我可以提取数据。

另外,在性能方面,让 javascript 将每一行单独发送到 python 还是在一个数组中一次全部发送到 python 会更有效吗?

脚本

app.py

@app.route('/send_emails')
def send_emails():
  contact = request.args.get('contact')
  remove = request.args.get('remove')

  print contact
  print remove

  return ('', 204) #No need to return anything

电子邮件.js

$('#batch-page .magic-button').click( function() {

  //Iterate over each company row
  $('#batch-page table tr.company-row').each(function(i, company){
    company = $(company);
    company_id = company.attr('class').split(' ')[1];

    //Assign arrays for emailing and removing comapnies
    var contact = [];
    var remove = [];

    //Check to see whether the contact or don't contact checkbox is checked
    if(company.children('td.contact-company').children('input').is(':checked')) {
      contact.push(company_id);
    } else if (company.children('td.remove-company').children('input').is(':checked')) {
      remove.push(company_id);
    }

    //Pass the data along to Python
    $.getJSON('/send_emails', {
      contact: contact,
      remove: remove
    });
  });
  $('div#batch-page').html('<p>Be patient, contacting companies!</p>');
});

batch.html

  {% for company in companies %}
    <tr class="company-row {{ company.id }}">
      <td class="company-name">
        <p>{{ company.company_name }}</p>
      </td>
      <td class="company-website">
        <div>
          <a href="{{ company.website }}" target="blank_">{{ company.website }}</a>
        </div>
      </td>
      <td class="company-email">
        <p>{{ company.email_address }}</p>
      </td>
      <td class="contact-company">
        <input type="checkbox" class="contact" for='{{ company.id }}'>
      </td>
      <td class="remove-company">
        <input type="checkbox" class="dont-contact" for='{{ company.id }}'></td>
      <td>
        <a class="btn btn-primary" data-toggle="collapse" data-target="#{{ company.id }}-info">Change Company Information</a>
      </td>
    </tr>
    <tr class="company-info-row">

      <td colspan="6" class="hiddenRow">
        <div class="accordion-body collapse" id="{{ company.id }}-info">
          <form action="" id="{{ company.id }}-edit-form" method="POST" class="update-company-form">
            <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
            <div class="col-md-4">
              <div class="form-group">
                <label for="{{ company.id }}-company-name">Company Name</label>
                <input type="text" value="{{ company.company_name }}" id="{{ company.id }}-company-name" class="form-control" name="company-name">
                <label for="{{ company.id }}-company-website">Company Website</label>
                <input type="text" value="{{ company.website }}" id="{{ company.id }}-company-website" class="form-control" name="company-website">
              </div>
            </div>
            <div class="col-md-4">
              <div class="form-group">
                <label for="{{ company.id }}-email-address">Company Email</label>
                <input type="text" value="{{ company.email_address }}" id="{{ company.id }}-email-address" class="form-control" name="company-email">
              </div>
              <div class="form-group">
                <input type="submit" form="{{ company.id }}-edit-form" class="btn btn-default" value="Update">
              </div>
            </div>
            <div class="col-md-4 ajax-message">
              <div>
                <i class="fa fa-clock-o fa-2x"></i>
                <p style="display: inline-block;">Date scraped on: {{ company.scraped_on }}</p>
              </div>
            </div>
          </form>
        </div>
      </td>
    </tr>
  {% endfor %}

更新 #1

尝试使用 json 模块中的加载方法加载请求,我收到以下错误消息:

Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/wyssuser/Desktop/dscraper/app.py", line 82, in send_emails
    content = json.loads(request.json)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
TypeError: expected string or buffer

【问题讨论】:

标签: javascript python json flask


【解决方案1】:

首先jQuery.getJSON() 使用您将其作为查询参数传递的 JSON 对象发出 GET 请求。

这里的问题是jQuery.getJSON() 以非传统方式序列化列表。因此,如果您查看浏览器发送的请求,它看起来像:

http://example.com/?contact[]=me&contact[]=others&contact[]=hr&remove[]=you&remove[]=doug

现在,Flask 会将该查询字符串解析为一个 args 字典,其中包含 contact[] 和 remove[] 键,但由于您正在执行 `request.args.get('contact'),因此您什么也得不到

解决方案是在像这样传递给jQuery.getJSON()之前自己创建查询参数。这可以使用jQuery.param() 来完成:

//Assign arrays for emailing and removing companies
var contact = ["me", "others", "hr"];
var remove = ["you", "doug"];

//Pass the data along to Python
$.getJSON(
    '/send_emails',
    $.param({ contact: contact, remove: remove }, true)
);

注意true 传递给jQuery.param(),它以传统格式返回查询字符串,如下所示:

contact=me&contact=others&contact=hr&remove=you&remove=doug

现在,您可以使用 Flask 检索您的参数

contacts = request.args.getList('contact')
print(contacts) # ['me', 'others', 'hr'] 

【讨论】:

  • 我需要加密 JSON,还是 SSL 证书会像烧瓶中的其他东西一样处理它
  • 只要您使用 https(SSL 或 TLS),加密就会在连接层自动进行,因此无需加密任何内容。
【解决方案2】:

你需要从请求中获取json,

content = request.json

然后使用你最喜欢的 json 解析器将 json 解析成一个对象。

obj = json.loads(content)

要回答您的问题,“在性能方面,让 javascript 将每一行单独发送到 python 还是在一个数组中一次全部发送到 python 会更有效吗?”,将所有数据发送到一回一回。

【讨论】:

  • 我试过了,但我收到一条错误消息,基本上说 json 不是“字符串或缓冲区”
  • 当您从 javascript 访问您的 webapi 时,您需要确保您正在设置您的标头。您需要 Content-Type="application/json" 否则将不会设置请求的 json 部分。您还应该为您的返回类型添加 Accepts: "application/json"。
  • $.getJSON 发出一个GET 请求,并将数据作为查询字符串传递给它,因此request.json 中将没有任何内容
【解决方案3】:

有一个错字:contacts = request.args.getList('contact')。我想你会写contacts = request.args.getlist('contact')。

【讨论】:

    猜你喜欢
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    • 1970-01-01
    • 2021-08-16
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多