1

我正在尝试从 Ruby on Rails 应用程序中删除 YouTube 上的视频。我正在按照YouTube API 文档中的这些说明进行操作:

DELETE /feeds/api/users/default/uploads/VIDEO_ID HTTP/1.1
Host: gdata.youtube.com
Content-Type: application/atom+xml
Authorization: Bearer ACCESS_TOKEN
GData-Version: 2
X-GData-Key: key=DEVELOPER_KEY

我对 Ruby 的Net::HTTP课程不是很熟悉,但似乎无论我尝试什么,我都无法让请求正常工作。我已经仔细查看了有关从 YouTube 删除视频的许多其他 StackOverflow 问题,但我找不到解决这个特定问题的方法。我的代码如下,我已经替换了用户名、视频 ID、访问令牌和开发人员密钥。

url = URI.parse("https://gdata.youtube.com/feeds/api/users/[USER_NAME]/uploads/[VIDEO_ID]")
post_args = { 'Host' => 'gdata.youtube.com', 'GData-Version' => '2', 'Content-Type' => 'application/atom+xml', 'Authorization' => "Bearer [ACCESS_TOKEN]", 'X-GData-Key' => 'key=[DEVELOPER_KEY]' }
req = Net::HTTP::Delete.new(url.path)
req.set_form_data(post_args)

httpreq = Net::HTTP.new(url.host, url.port)
httpreq.use_ssl = true

resp = httpreq.start {|http| http.request(req) }

检查响应,我收到来自 YouTube 的错误 400(错误请求)。响应只是说“您的客户发出了格式错误或非法的请求。这就是我们所知道的”。

我提出的要求有问题吗?我已经一次又一次地对照模板检查它,我看不出它有什么问题。我知道我的访问令牌和开发人员密钥正在工作,因为我可以提出其他请求,例如视频上传。

我打印了 HTTP 请求的调试输出,据我所知,它看起来不错:

<- "DELETE /feeds/api/users/[USER_NAME]/uploads/[VIDEO_ID] HTTP/1.1\r\nAccept: */*\r\nUser-Agent: Ruby\r\nContent-Type: application/x-www-form-urlencoded\r\nHost: gdata.youtube.com\r\nContent-Length: 275\r\n\r\n"
<- "Host=gdata.youtube.com&GData-Version=2&Content-Type=application%2Fatom%2Bxml&Authorization=Bearer+[ACCESS_TOKEN]&X-GData-Key=key%3D[DEVELOPER_KEY]"

我唯一能看到的可能问题是,在请求的第一行中,“Content-Type”设置为“application/x-www-form-urlencoded”。同样,我不是 HTTP 请求方面的专家,我不确定第一行中设置的 Content-Type 与我明确设置为“application/atom+xml”的 Content-Type 之间有什么区别,后者出现在第二行请求的行。但是,经过一番挖掘,我发现该set_form_data方法会自动将内容类型设置为“application/x-www-form-urlencoded”,因此我尝试在代码中添加以下行:

req.content_type = 'application/atom+xml'

就在这条线之后

req.set_form_data(post_args)

当我这样做时,我确实在请求中看到了相应的变化:

<- "DELETE /feeds/api/users/[USER_ID]/uploads/[VIDEO_ID] HTTP/1.1\r\nAccept: */*\r\nUser-Agent: Ruby\r\nContent-Type: application/atom+xml\r\nHost: gdata.youtube.com\r\nContent-Length: 275\r\n\r\n"
<- "Host=gdata.youtube.com&GData-Version=2&Content-Type=application%2Fatom%2Bxml&Authorization=Bearer+[ACCESS_TOKEN]&X-GData-Key=key%3D[DEVELOPER_KEY]"

但是,我仍然从 YouTube 得到完全相同的回复。错误 400,错误的请求。这到底是怎么回事??

4

1 回答 1

0

当然,问了我的问题10分钟后,我就找到了答案。我不理解 HTTP 标头字段和表单参数之间的区别,我对此并不感到难过,因为在 Ruby 文档Net::HTTP或 YouTube API 中的任何地方都没有解释它。我感到困惑的原因是因为上传视频,您可以提供所有值,如 Authorization 和 Content-Type 作为表单数据,所以我的问题中的上述方法工作正常。要删除视频,您必须提供这些值作为标题的一部分,而不是表单数据。至少,这是我现在的理解。

无论如何,万一有人遇到这个问题,这为我解决了它:

req = Net::HTTP::Delete.new(url.path)
req['GData-Version'] = '2'       # this syntax sets header fields & values
req['Authorization'] = "..."
req['X-GData-Key'] = "..."

req.content_type = 'application/atom+xml'

httpreq = Net::HTTP.new(url.host, url.port)
httpreq.use_ssl = true

resp = httpreq.start {|http| http.request(req) }

另一种情况是,文档作者的一个解释性句子可以节省两个小时的浪费时间。如果我有一个镍...

于 2013-02-27T20:28:11.620 回答