向Sinatra发出Ajax调用

时间:2017-01-22 02:19:02

标签: jquery html ruby ajax sinatra

所以我所做的就是使用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);
      }
    });
  });
});

2 个答案:

答案 0 :(得分:1)

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

1。的Javascript

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

您可以通过在AJAX调用后添加return false;或使用<button>而不是<input type="submit">元素来解决此问题。

2。屈

您正在使用client之类的全局对象,而没有适当的锁定机制。我没有看到yelp gem提到任何关于线程安全的东西,所以我们必须假设它不是。如果您同时有两个请求,则client可以由两个不同的线程同时访问,并且失败。您必须始终警惕在Sin​​atra中,每个请求都可以在不同的线程中处理,因此可以同时处理同一路径上的两个同时请求。

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

答案 1 :(得分:0)

(抱歉,只有评论才有声誉,但我想提供帮助) 今天没有时间回答,但我会给你一个类似的例子。

https://github.com/pgaspar/oqfc

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

我向服务器发送了哪个建议被投票(向上按钮或向下按钮),我从服务器收回投票数。

希望它有所帮助,明天会找到你。

---更新---

不要将新呈现的代码插入#babyResult,而是使用它创建一个console.log并显示它