【问题标题】:Making an Ajax call to Sinatra向 Sinatra 发出 Ajax 调用
【发布时间】:2017-06-06 19:13:30
【问题描述】:

所以我所做的是使用 Sinatra 创建一个页面,用户可以在其中输入信息,当提交该信息时,我使用 post 方法抓取它,然后使用他们提交的该信息进行搜索调用在 Yelp api 中,我收到了响应,我想用该响应的结果更新页面,而不是转到其他页面。

到目前为止,我可以获取用户输入、进行搜索并接收搜索结果,但之后我尝试对 post 方法进行 ajax 调用,将 erb 返回到 ajax 调用,然后插入该 erb 文件在页面底部的 div 中。我不断收到 500 内部服务器错误,我不知道为什么。有没有更简单或更直接的方法来完成我想做的事情?我的代码如下。

Main.rb 文件:

require 'sinatra'
require 'yelp'
require 'openssl'
require 'json'
require 'net/http'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

get '/' do
  erb :layout
end

client = Yelp::Client.new({ My keys
                          })

 hash = {limit: 5, category_filter: 'food'}
locale = { lang:'eng' }


post '/food' do
     name = params[:name]
     city = params[:city]
     nationality = params[:nationality]
     meal = params[:birth_time]
     stork = params[:stork]
     searchStr = city + " " + name + " " + nationality + " " + meal
     response = client.search(searchStr)
     @business = response.businesses[0].name
     @business_img = response.businesses[0].image_url
     @url = response.businesses[0].url
     @rating_img = response.businesses[0].rating_img_url

     erb :baby
end

Layout.erb 文件:

<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="/script.js"></script>
</head>

<body>

  <form method="POST" action="/food" id="babyDetails">
    <p> Name of Child: <input type="text" name="name"></p>
    <p> Hometown: <input type="text" name="city"></p>
    <p>
      Nationality:
      <select name="nationality">
        <option value="American">American</option>
        <option value="Chinese">Chinese</option>
        <option value="Greek">Greek</option>
        <option value="Bakery">Fairy</option>
        <option value="Haitian">Haitian</option>
        <option value="Indian">Indian</option>
        <option value="Japanese">Japanese</option>
        <option value="Mexican">Mexican</option>
      </select>

    </p>
    <p>
      Time of Delivery:
      <select name="birth_time">
        <option value="morning">Morning</option>
        <option value="afternoon">Afternoon</option>
        <option value="night">Night</option>
      </select>
    </p>
    <p>
      I Want The Stork To Deliver My Baby?  <input type="checkbox" name="stork" value="yes">
    </p>

    <input type="submit" value="Where Can I Find My Baby?" id="submitBtn"/>
  </form>
   <div id="babyResult">

   </div>
</body>

</html>

Baby.erb 文件:

<div>
  <h1>You can find your baby at:</h1>
  <br />
  <h5><%= @business %></h5>
  <img src='<%= @business_img %>'/>
</div>

script.js 文件:

$(document).ready(function() {

  $("#submitBtn").click( function(){
    console.log("Works");
    $('#babyResult').html("")
    $.ajax({
      type: 'post',
      url: '/food',
      success: function(result) {
        $('#babyResult').html(result);
      }
    });
  });
});

【问题讨论】:

    标签: jquery html ruby ajax sinatra


    【解决方案1】:

    我没有测试,但我认为你有两个问题。

    1。 Javascript

    您将 AJAX 调用绑定到提交按钮,但在回调结束时您没有 return false;click 事件被你的 Javascript 代码处理后,它会冒泡,浏览器会执行正常的表单提交。所以最终结果是一次点击两次POST请求。

    例如,您可以通过在 AJAX 调用之后添加 return false; 或使用 &lt;button&gt; 而不是 &lt;input type="submit"&gt; 元素来解决此问题。

    2。西纳特拉

    您正在使用像client 这样的全局对象,但没有适当的锁定机制。我没有看到yelp gem 提到任何关于线程安全的内容,所以我们必须假设它不是。如果您同时有两个请求,client 可能会被两个不同的线程同时访问,并且会失败。您必须时刻注意,在 Sinatra 中,每个请求都可以在不同的线程中处理,因此同一路由上的两个同时请求可以同时处理。

    您可以在路由中创建一个新的Yelp::Client 对象(即,每次需要时),或者在调用client 上的方法之前使用mutex

    【讨论】:

      【解决方案2】:

      (对不起,没有声誉只能评论,但我想帮忙) 今天真的没有时间回答,但我会给你一个类似的例子。

      https://github.com/pgaspar/oqfc

      在文件夹 oqfc/public/js/ajax.js 中

      我将投票的建议发送到服务器(向上按钮或向下按钮),然后我从服务器收到投票计数。

      希望对你有帮助,明天给你。

      --- 更新 ---

      不要将新的渲染代码插入#babyResult,而是用它制作一个console.log并显示它

      【讨论】:

        猜你喜欢
        • 2012-11-29
        • 1970-01-01
        • 2015-09-25
        • 2013-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多