在使用HATEOAS设计RESTful Web服务时,将链接显示为完整URL(" http:// server:port/application/customers/1234 ")与仅路径("/ application /")的优缺点是什么?客户/ 1234" )?
当人们说"相对uri"时,存在一种微妙的概念歧义.
根据RFC3986的定义,通用uri包含:
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] hier-part = "//" authority path-abempty / path-absolute / path-rootless / path-empty foo://example.com:8042/over/there?name=ferret#nose \_/ \______________/\_________/ \_________/ \__/ | | | | | scheme authority path query fragment
棘手的是,当省略方案和权限时,"路径"部分本身可以是绝对路径(以"/"开头)或"无根"相对路径.例子:
一个绝对URI或一个完整的URI:"http://example.com:8042/over/there?name=ferret"
这是一个相对的uri,绝对的路径:"/ over/there"
这是一个相对的uri,相对路径:"here"或"./here"或"../here"等.
因此,如果问题是"服务器是否应该在宁静响应中产生相对路径 ",则答案为"否",详细原因可在此处获得.我认为大多数人(包括我)反对"相对uri"实际上反对"相对路径".
实际上,大多数服务器端MVC框架可以很容易地生成具有绝对路径的相对uri,例如"/ absolute/path/to/the/controller",并且问题变成"服务器实现是否应该作为scheme的前缀:// hostname :绝对路径前面的端口".就像OP的问题一样.我对这个不太确定.
一方面,我仍然认为服务器返回完整的uri是建议的.但是,服务器永远不应该像这样硬编码源代码中的hostname:port事物(否则我宁愿用绝对路径回退到相对uri).解决方案是服务器端始终从HTTP请求的"主机"标头获取该前缀.不确定这是否适用于所有情况.
另一方面,客户端连接"http://example.com:8042"
和绝对路径似乎不是很麻烦.毕竟,客户端在向服务器发送请求时已经知道了该方案和域名吗?
总而言之,我会说,建议使用绝对uri,可能使用绝对路径回退到相对uri,从不使用相对路径.
这取决于谁在编写客户端代码.如果您正在编写客户端和服务器,那么它没有太大区别.您将要么在客户端或服务器上构建URL的痛苦.
但是,如果您正在构建服务器并且您希望其他人编写客户端代码,那么如果您提供完整的URI,他们会更加喜欢您.解析相对URI可能有点棘手.首先,如何解决它们取决于返回的媒体类型.Html具有基本标记,Xml可以在每个嵌套元素中包含xml:base标记,Atom提要可以在提要中具有基础,并且内容中具有不同的基础.如果您没有向客户端提供有关基本URI的明确信息,那么他们必须从请求URI获取基本URI,或者从Content-Location标头获取基本URI!并留意那个尾随的斜线.通过忽略最后一个斜杠右侧的所有字符来确定基URI.这意味着在解析相对URI时,尾随斜杠现在非常重要.
唯一需要提及的另一个问题是文档大小.如果要返回大项目列表,其中每个项目可能有多个链接,则如果不压缩实体,则使用绝对URL可以向实体添加大量字节.这是一个性能问题,您需要根据具体情况决定它是否重要.
唯一真正的区别似乎是,如果客户端使用绝对URI而不必从相对版本构造它们,那么对客户端来说更容易.当然,这种差异足以影响我做绝对版本.
随着您的应用程序扩展,您可能希望进行负载平衡,故障转移等.如果您返回绝对URI,那么您的客户端应用程序将遵循您不断发展的服务器配置.
我的组织使用RayLou的三分法选择了偏爱(2)。主要原因是为了避免XSS(跨站点脚本)攻击。问题是,如果攻击者可以将自己的URL根注入到来自服务器的响应中,则随后的用户请求(例如具有用户名和密码的身份验证请求)可以转发到攻击者自己的服务器*。
有些人提出了能够将请求重定向到其他服务器以进行负载平衡的问题,但是(虽然这不是我的专业领域),我敢打赌,有更好的方法来启用负载平衡,而不必将客户端显式重定向到其他服务器。主机。
*请让我知道这种推理方法是否存在缺陷。当然,目标不是阻止所有攻击,而是至少阻止一种攻击途径。