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

|| 我的情况是我有一个POST cgi脚本,该脚本生成并返回一个媒体文件(mp3)。此脚本的客户端之一希望使用iOS媒体播放器(MPMoviePlayer)对象,该对象仅将NSURL(基本上是URL字符串)作为输入。问题在于,在iOS上,仅使用NSURL不能发送POST参数。   iOS当然可以使用其他对象(NSURLRequest)来发布请求,但是脚本需要花费一些时间才能运行,因此无法运行请求,将文件保存到磁盘然后将文件传递给媒体播放器对象。 起初我以为也许我们应该改用GET,尽管它不是很好的RESTful设计,但只要设置了robots.txt,它就不会那么糟糕。但是我在SO上发现了一个类似的问题,明确地认为,如果您要使用cgi脚本更改服务器状态,则GET是一个坏主意,即使这样做会使访问更容易: 使用GET而不是POST删除经过身份验证的页面后面的数据 除了重写媒体播放器对象之外,我看不出一种简单的方法。 谁能在仍然使用基于url的播放器的情况下建议将脚本更改为GET的替代方法? 使用GET最可怕的事情不是安全/恶意黑客,因为这些问题中的大多数也会影响POST。我主要担心的是搜索引擎robots / etc中的新\ fixes \会忽略robots.txt。还有别的事吗? 另外,如果有理由为什么这里可以接受GET,那么我也将对该答案感兴趣。我想知道搜索引擎/机器人问题在这里是否没有问题,因为我们没有一个http表单可以在任何地方提交GET请求(因为iOS应用程序将在应用程序内部执行该请求),而cgi脚本却没有定义与之一起使用的请求方法(尽管他们可以检测到并中止)。     
已邀请:
我同意在这种情况下POST是正确的HTTP方法,当客户端请求包含导致在服务器上创建文件的参数时。除了作为一种好的做法,您链接到的浏览器预取问题还是一个很好的告诫,它可能会导致错误(Google自此恢复了此“功能”)。 但是,假设您要继续使用GET而不是重写以使用POST,我将提供一些建议。 关于搜索引擎爬网,这是一个合理的问题。最近,我一直在使用机器人排除标准进行大量工作,以我的经验,这是一个遵循良好的标准,所有合法爬网程序(例如搜索引擎)都遵循该标准。在这一点上,它已经有15多年的历史了,基本保持不变,语法非常简单。尽管最近Google和公司正在抓取越来越多的内容(新文件类型,内部搜索表单),但我无法想象他们违反了明确的“ 0”规则。无论如何,请务必针对这些URL模式实施并测试robots.txt,这应该可以解决搜索引擎问题。 我不知道这些URL是否以任何方式向用户公开(浏览器地址栏,它们可以右键单击的网页链接)还是仅仅是HTTP流量的一部分-但是否仅是后者,您不必担心。如果不通过您网站上的链接跟踪此类深层URL,通常会通过用户通过电子邮件,Twitter等共享链接的方式来对这些深层URL进行索引。 robots.txt而不对其编制索引,但是在Twitter上仍然可以找到它对于您来说仍然是一个问题。因此,请尽可能使所有敏感URL仅在后台运行(我敢肯定,您99.9%的用户不会费心嗅探TCP来获取URL共享)。 至于缓解GET的其他问题,我建议将随机数与会话密钥一起用作GET URL的一部分。这是Web应用程序中用于防止CSRF的非常标准的事情,它会使这些GET URL在客户端会话中只能使用一次(如果限制太多,则可以使它们对会话的访问时间更长。) 。请使用基于时间的哈希值(而不是随机数)。当随机数到期时,返回404或30X重定向。 您可以执行其他操作,而不是让CGI直接返回.mp3文件流,而是让它执行HTTP重定向到返回该文件的第二个URL。根据您是否希望第二个URL是\“ public \” URL,可以使用永久(301)或临时(302/303)响应代码。搜索引擎不会为初始GET URL编制索引,因为它会导致重定向,并且不会保留在浏览器地址栏中供用户复制/粘贴。 确保这些URL是一次性的,只有一个会话可以解决安全性/负载问题。我能想到的唯一例外是浏览器预取情况。 在预取...时,HTML规范正朝着使用ѭ1doing进行选择性链接预取(当前,
type=\"next\"
link
标签中完成此操作,但没有等同于指定可以/应该预取
a
标签)的方法,而不是默认的\“预取一切行为。一个相关的问题是,代理也可能会进行预取(例如,办公室网络的Squid或像Opera Mini这样的移动浏览器,它们使用代理来获取和重新压缩图像),但是我不知道目前正在执行的任何操作。因此,我认为您在这方面没有真正要担心的事情,但是如果您对此抱有偏执,那么解决方法是遵循规则,并在修改服务器状态时仅使用POST。     
因此,关键在于GET请求会即时生成mp3,因此,是否可行取决于应用程序的几个功能: 如果mp3可重复使用,则应用应提前或按要求生成mp3,然后缓存结果。因此,后续的GET请求只是为数据提供服务,这是对GET的正确使用。 如果mp3在该下载实例中是用户自定义的,则POST请求更为合适,因为这是对系统在特定上下文中生成资源的请求。此上下文由POST中的数据提供。请记住,REST不是关于POST的含义的宗教-您可以使用REST来做类似这样的事情,而无需走出模型。 相反,如果您担心由机器人下载,则可以使用一些技巧: 按IP限制对资源的访问。对该资源的多次请求可以限制为每分钟一次,或者看似合适。这将为您提供防御拒绝服务攻击的防护。 阻止对已知机器人的资源访问。有公共索引器的IP地址列表,您可以使用它们在资源的GET上返回403(禁止)响应。 根据HTTP请求标头过滤对资源的访问。例如,您可以查看User-Agent并确保它是您的“受支持的”浏览器之一。这可能是最不建议的。 希望能有所帮助。     
GET应该没问题。 这里的重要部分是客户端不请求服务器状态更改。 请参阅规格:   自然,不可能确保服务器不会由于执行GET请求而产生副作用;实际上,一些动态资源认为该功能。这里的重要区别是用户没有要求副作用,因此不能对它们负责。     
GET应该没问题。您无需盲目遵循一般用途的规范。 在您的情况下,使用GET更容易-那么为什么不使用它呢?     

要回复问题请先登录注册