Rails Ajax ->西纳特拉->亚马逊 API 和返回

发布于 2024-12-15 16:45:57 字数 1272 浏览 2 评论 0原文

我不确定我是否真正理解 Sinatra 的工作原理。

我想在我的 Rails 应用程序中使用 Amazon 的 API 获取一些产品。但是 HTTP 请求会阻塞 IO。我得到了创建 Sinatra 应用程序并向那里发出 Ajax 请求的提示。

Ajax:(来自我的 Rails 应用程序)

$.ajax({
  url: "http://sinatra.mydomain.com",
  dataType: "json",
  success: function(data) {
    console.log(data);
  }
});

Sinatra 应用程序:(我还使用了 Sinatra-synchrony gem)

require 'sinatra'
require 'sinatra/synchrony'
require 'erb'
require 'rest-client'
require 'amazon_product'

Sinatra::Synchrony.overload_tcpsocket!

get '/' do  
  req = AmazonProduct["us"]
  req.configure do |c|
    c.key    = "KEY"
    c.secret = "SECRET"
    c.tag    = "TAG"
  end
  req << { :operation    => 'ItemSearch',
           :search_index => "DVD",
           :response_group => %w{ItemAttributes Images},
           :keywords => "nikita",
           :sort => "" }
  resp = req.get
  @item = resp.find('Item').shuffle.first

  erb :layout, :locals => { :amazon_product => @item }
end

Layout.erb:(渲染如果我在浏览器中访问此网址,就可以了)

<%= amazon_product %>

问题

我的 Ajax 响应是 200 OK,但响应为空。
我不明白出了什么问题。请指教。

I'm not sure that I really understand how Sinatra works.

I'd like to get some products from Amazon using their API, in my Rails app. But HTTP requests are blocking the IO. I got the tip to create a Sinatra app and make an Ajax request to there instead.

Ajax: (From my Rails app)

$.ajax({
  url: "http://sinatra.mydomain.com",
  dataType: "json",
  success: function(data) {
    console.log(data);
  }
});

Sinatra app: (I also make use of the Sinatra-synchrony gem)

require 'sinatra'
require 'sinatra/synchrony'
require 'erb'
require 'rest-client'
require 'amazon_product'

Sinatra::Synchrony.overload_tcpsocket!

get '/' do  
  req = AmazonProduct["us"]
  req.configure do |c|
    c.key    = "KEY"
    c.secret = "SECRET"
    c.tag    = "TAG"
  end
  req << { :operation    => 'ItemSearch',
           :search_index => "DVD",
           :response_group => %w{ItemAttributes Images},
           :keywords => "nikita",
           :sort => "" }
  resp = req.get
  @item = resp.find('Item').shuffle.first

  erb :layout, :locals => { :amazon_product => @item }
end

Layout.erb: (renders fine if I go to this Url in the browser)

<%= amazon_product %>

Problem:

My Ajax response is a 200 OK but with an empty response.
I'm can't figure out what's wrong. Please advise.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泼猴你往哪里跑 2024-12-22 16:45:57

您似乎遇到了ajax“跨域安全”问题。尝试使用 JSONP (带填充的 JSON)。

更改您的 sinatra get 处理程序:

get '/' do  
  req = AmazonProduct["us"]
  req.configure do |c|
    c.key    = KEY
    c.secret = SECRET
    c.tag    = TAG
  end
  req << { :operation    => 'ItemSearch',
           :search_index => "DVD",
           :response_group => %w{ItemAttributes Images},
           :keywords => "nikita",
           :sort => "" }
  resp = req.get
  @item = resp.find('Item').shuffle.first

  content_type :json
  callback = params.delete('callback') # jsonp
  json = @item.to_json

  if callback
    content_type :js
    response = "#{callback}(#{json})" 
  else
    content_type :json
    response = json
  end
  response
end

并更改您的 Ajax 请求:

$.getJSON("http://address_of_sinatra?callback=?",
  function(data) {
    console.log(data);
});

或者您可以将 dataType: 'jsonp' 添加到您的 $.ajax请求。
之后,您应该在 js 调试器中看到 data 对象(至少它在我的情况下工作:D)

It seems that you've faced with ajax 'cross-domain security' problem. Try to use JSONP (JSON with padding).

Change your sinatra get handler:

get '/' do  
  req = AmazonProduct["us"]
  req.configure do |c|
    c.key    = KEY
    c.secret = SECRET
    c.tag    = TAG
  end
  req << { :operation    => 'ItemSearch',
           :search_index => "DVD",
           :response_group => %w{ItemAttributes Images},
           :keywords => "nikita",
           :sort => "" }
  resp = req.get
  @item = resp.find('Item').shuffle.first

  content_type :json
  callback = params.delete('callback') # jsonp
  json = @item.to_json

  if callback
    content_type :js
    response = "#{callback}(#{json})" 
  else
    content_type :json
    response = json
  end
  response
end

And change your Ajax request:

$.getJSON("http://address_of_sinatra?callback=?",
  function(data) {
    console.log(data);
});

Or you can add dataType: 'jsonp' to your $.ajax request.
After that you should see data object in js debugger (at least it's working in my case :D )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文