CGI:当客户端只能使用URL字符串时,使用GET而不是POST

时间:2011-05-26 01:22:47

标签: iphone ios http cgi

我的情况是我有一个POST cgi脚本,它生成并返回一个媒体文件(mp3)。此脚本的一个客户端想要使用仅使用NSURL(基本上是URL字符串)作为输入的iOS媒体播放器(MPMoviePlayer)对象。问题是在iOS上,POST参数将无法仅使用NSURL发送。   iOS当然可以使用其他对象(NSURLRequest)发布请求,但脚本需要一段时间才能运行,因此运行请求,将文件保存到磁盘,然后将文件传递给媒体播放器ojbect是不可接受的。

起初我想也许我们应该改为GET,虽然它不是很好的RESTful设计,但只要我设置了robots.txt就不会那么糟糕。但我在SO上发现了一个类似的问题,并且明确认为,如果你用cgi脚本改变服务器状态,GET是一个坏主意,即使它会使访问更容易:

Using GET instead of POST to delete data behind authenticated pages

我没有看到重写媒体播放器对象的简单方法。 任何人都可以建议在使用基于网址的播放器时将脚本更改为GET的替代方法吗?

使用GET最可怕的不是安全/恶意黑客,因为大多数这些问题也会影响POST。我主要担心搜索引擎机器人/等中忽略robots.txt的新“修复”。还有别的吗?

此外,如果有理由说明为什么GET可以接受,我也会对这个答案感兴趣。我想知道搜索引擎/机器人问题是否是一个非问题,因为我们不会有任何地方提交GET请求的http表单(因为iOS应用程序将在应用程序内执行),并且cgi脚本没有定义他们使用的请求方法(虽然他们可以检测到并中止。)

4 个答案:

答案 0 :(得分:1)

因此,关键是GET请求即时生成mp3,因此这是否可行取决于应用程序的一些功能:

  1. 如果mp3可重复使用,应用程序应该提前或按需生成mp3,然后缓存结果。因此,后续的GET请求只是提供数据,这是正确使用GET。

  2. 如果mp3是针对该一个下载实例中的用户定制的,那么POST请求更合适,因为这是对系统在特定上下文中生成资源的请求。此上下文由POST中的数据提供。请记住,REST并不是关于POST的含义的宗教信仰 - 您可以使用它来做各种各样的事情而不会偏离模型。

  3. 如果您担心有关机器人的下载,那么您可以采用一些技巧:

    1. 根据IP限制对资源的访问。对资源的多个请求可以限制为每分钟一次,或者任何合适的请求。这可以帮助您抵御拒绝服务攻击。

    2. 阻止访问已知机器人的资源。有常见索引器的IP地址列表,您可以使用它们在资源的GET上返回403(禁止)响应。

    3. 根据HTTP请求标头过滤对资源的访问。例如,您可以查看User-Agent并确保这是您的“支持”浏览器之一。这可能是最不可取的。

    4. 希望有所帮助。

答案 1 :(得分:1)

我同意在这种情况下POST是正确的HTTP方法,当客户端请求包含导致在服务器上创建文件的参数时。除了这是一个很好的做法之外,你所链接的浏览器预取问题是一个很好的警示故事(谷歌已经恢复了这个“功能”)。

但是,假设您正在使用GET而不是重写使用POST,我会给出一些建议。

关于搜索引擎抓取,这是一个合理的问题。我最近在机器人排除标准方面做了很多工作,根据我的经验,这是一个观察良好的标准,所有合法的抓取工具都会跟随搜索引擎。在这一点上,它已经超过15年,基本上没有变化,语法非常简单。虽然谷歌和公司现在正在抓取越来越多的东西(新的文件类型,在搜索表单中),但我无法想象它们违反了明确的Disallow规则。无论如何,一定要为这些URL模式实现和测试robots.txt,这应该解决搜索引擎问题。

我不知道这些URL是否以任何方式暴露给用户(浏览器地址栏,他们可以右键单击的网页链接)或者仅仅是HTTP流量的一部分 - 但如果它只是后者,你没什么可担心的。这些深层网址通常会被编入索引,如果它们没有通过您网站上的链接,是由用户通过电子邮件,Twitter等分享链接。如果有人发推文链接,googlebot抓取它,谷歌将服从机器人.txt并没有索引它,但它可能仍然是一个问题,你可以在Twitter找到它。因此,尽可能使任何敏感网址仅在后台运行(我确信99.9%的用户不会费心嗅探TCP以获取要共享的网址。)

至于缓解GET的其他问题,我建议使用nonce作为GET URL的一部分,以及会话密钥。这是Web应用程序中一个非常标准的东西,可以防止CSRF,并且它会使这些GET URL仅在客户端会话中使用一次(如果限制太多,您可以将它们更长时间用于会话...使用时间基于哈希而不是随机数)。当nonce过期时,返回404或30X重定向。

您可以做的其他事情是,不要让CGI直接返回.mp3文件流,而是将HTTP重定向到返回文件的第二个URL。根据您是否希望第二个URL成为“公共”URL,您可以使用永久(301)或临时(302/303)响应代码。搜索引擎不会将初始GET URL编入索引,因为它会导致重定向,并且不会在浏览器地址栏中保留,以供用户复制/粘贴。

确保这些URL是一次性的,仅一个会话将解决安全/负载问题。我能想到的唯一例外是浏览器预取案例。

预取... HTML规范正朝着使用type="prefetch"选择link prefetching的方向发展(目前,type="next"link标记中完成此操作,但没有相应的内容指定可以/应该预取a标记,而不是“默认预取所有内容”行为。一个相关的问题是,也可能有代理预取(例如,办公网络的Squid,或Opera Mini等使用代理获取和重新压缩图像的移动浏览器),但我目前不知道做这个。所以,我不认为你在这方面有任何真正担心,但如果你想对此有偏见,那么出路就是遵循规则并在修改服务器时使用POST状态。

答案 2 :(得分:0)

GET应该没问题。

这里的重要部分是客户端请求服务器状态更改。

请参阅specification

  

当然,无法确保服务器不会因执行GET请求而产生副作用;实际上,一些动态资源会考虑这个功能。这里的重要区别是用户没有请求副作用,因此不能对他们负责。

答案 3 :(得分:0)

GET应该没问题。您不需要盲目遵循为一般目的而编写的规范。 在您的情况下,使用GET会更容易 - 那么为什么不使用?