使用 d3.json 查询 sinatra 应用程序在 localhost 上工作正常,但在部署时因禁止而失败

Posted

技术标签:

【中文标题】使用 d3.json 查询 sinatra 应用程序在 localhost 上工作正常,但在部署时因禁止而失败【英文标题】:Using d3.json to query a sinatra app works fine on localhost, but fails with forbidden when deployed 【发布时间】:2015-05-23 09:37:09 【问题描述】:

我有一个简单的 Sinatra 应用程序。一个端点为一个页面提供服务,该页面包括一个用 d3.js 呈现的图表。 d3 使用对d3.json 的调用从第二个端点“\tasks.json”加载数据。

  d3.json('/tasks.json', function(json)  ... 

这适用于我的 Windows PC,但是当推送到生产环境(Linux 机器)时,我没有显示任何数据。使用 chrome 查看网络流量,我可以看到“tasks.json”调用失败并显示以下标头:

HTTP/1.0 403 Forbidden
Server: openresty
Date: Fri, 20 Mar 2015 02:39:06 GMT
Content-Type: text/plain
Content-Length: 9
X-Content-Type-Options: nosniff
X-Cache: MISS from proxy.xx.xx.xx
X-Cache-Lookup: MISS from proxy.xx.xx.xx:3128
Via: 1.0 proxy.xx.xx.xx (squid/3.1.6)
Proxy-Connection: keep-alive

但是....如果我直接在浏览器中打开相同的“tasks.json”端点,它可以正常加载。

HTTP/1.0 200 OK
Server: openresty
Date: Fri, 20 Mar 2015 02:46:53 GMT
Content-Type: application/json
Content-Length: 3524
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
X-Frame-Options: ALLOW-FROM *
X-Content-Type-Options: nosniff
X-Cache: MISS from proxy.xx.xx.xx
X-Cache-Lookup: MISS from proxy.xx.xx.xx:3128
Via: 1.0 proxy.xx.xx.xx (squid/3.1.6)
Proxy-Connection: keep-alive

在我的 sinatra 应用中,我还关闭了保护。

  set :protection, false

有什么想法吗?

失败的调用具有以下请求标头

GET http://project_dash.locallan.link/tasks.json HTTP/1.1
Host: project_dash.locallan.link
Proxy-Connection: keep-alive
accept: application/json,*/*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/40.0.2214.115 Safari/537.36
DNT: 1
Referer: http://project_dash.locallan.link/gantt
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-AU,en;q=0.8,en-US;q=0.6
Cookie: __utma=10890537.1709214504.1411711051.1411711051.1411711051.1; __utmz=10890537.1411711051.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _sio=30220c08-f9ff-4584-8218-9145a2a1cde1----; ajs_user_id=null; ajs_group_id=null

工作调用具有以下标头

GET http://project_dash.locallan.link/tasks.json HTTP/1.1
Host: project_dash.locallan.link
Proxy-Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-AU,en;q=0.8,en-US;q=0.6
Cookie: __utma=10890537.1709214504.1411711051.1411711051.1411711051.1; __utmz=10890537.1411711051.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _sio=30220c08-f9ff-4584-8218-9145a2a1cde1----; ajs_user_id=null; ajs_group_id=null

注意:如果它用 jquery ajax 调用替换 d3.json 调用,则它开始工作。因此,我认为 d3 必须在它的请求中设置一个属性,即 Sinatra/Rack 管道被 403 阻塞。

有什么方法可以计算出堆栈的哪一部分返回了 403?

我将服务器作为 docker 容器运行,docker 日志显示请求进入但没有解释 403。

22:58:11 web.1  | 10.10.254.12 - - [22/Mar/2015:22:58:11 +0000] "GET / HTTP/1.1" 200 1675 0.0025
22:59:01 web.1  | 10.10.240.18 - - [22/Mar/2015:22:59:01 +0000] "GET /gantt HTTP/1.0" 200 2123 0.0283
22:59:02 web.1  | 10.10.240.18 - - [22/Mar/2015:22:59:02 +0000] "GET /js/gantt-chart-d3.js HTTP/1.0" 200 6325 0.1259
22:59:02 web.1  | 10.10.240.18 - - [22/Mar/2015:22:59:02 +0000] "GET /js/gantt.js HTTP/1.0" 200 1367 0.0015
22:59:02 web.1  | 10.10.240.18 - - [22/Mar/2015:22:59:02 +0000] "GET /css/style.css HTTP/1.0" 200 30 0.0257
22:59:04 web.1  | 10.10.240.18 - - [22/Mar/2015:22:59:04 +0000] "GET /tasks.json HTTP/1.0" 403 9 0.4286
22:59:11 web.1  | 10.10.254.12 - - [22/Mar/2015:22:59:11 +0000] "GET / HTTP/1.1" 200 1675 0.0138
22:59:11 web.1  | 10.10.240.18 - - [22/Mar/2015:22:59:11 +0000] "GET /tasks.json HTTP/1.0" 200 3524 0.0873

【问题讨论】:

失败的 javascript 请求是否来自不同的域? 没有。所有内容均来自同一站点。 【参考方案1】:

我不明白为什么会这样,但最后我做了以下事情。

  get '/:file.json' do |file|
    #content_type :json
    content_type  = 'text/json'
    File.read("#file.json")
  end

我更改了“content_type”行以将内容设置为“text/json”。这允许 D3 库正确加载数据。

我认为这相当于它上面的行。

【讨论】:

以上是关于使用 d3.json 查询 sinatra 应用程序在 localhost 上工作正常,但在部署时因禁止而失败的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 HAML 提高 Sinatra 性能?

Sinatra 应用程序作为机架中间件 TimeOut Rails 3

在一个进程多个数据库连接 sinatra 应用程序中使用啥 ORM?

与Sinatra一起设计

使用 Sinatra 提供静态文件

在 Sinatra 和 Rails 之间共享 Yaml 配置文件