【发布时间】:2021-08-11 18:42:10
【问题描述】:
根据 Roy Fielding 的博士论文 Architectural Styles and the Design of Network-Based Software Architectures,HTTP cookie 违反 REST 架构风格,因为它们独立于应用程序状态并且没有语义,@987654321 @:
对协议进行了不适当的扩展以支持与通用接口的所需属性相矛盾的功能的一个示例是以 HTTP cookie 的形式引入站点范围的状态信息。 Cookie 交互无法匹配 REST 的应用程序状态模型,通常会导致典型浏览器应用程序的混乱。
Cookie 也违反了 REST,因为它们允许在没有充分识别其语义的情况下传递数据,从而成为安全和隐私方面的问题。 cookie 与 Referer [sic] 标头字段的组合使得在用户浏览网站时跟踪他们成为可能。
因此他提出了以下替代方案:
因此,Web 上基于 cookie 的应用程序永远不会可靠。应该通过匿名身份验证和真正的客户端状态来完成相同的功能。使用上下文设置 URI 而不是 cookie,明智地使用上下文设置 URI 可以更有效地实现涉及偏好的状态机制,其中明智意味着每个状态一个 URI,而不是由于嵌入用户 ID 而导致的无限数量的 URI。同样,通过在超媒体数据格式中定义购物项目的语义,允许用户代理选择和存储这些项目,可以更有效地实现使用 cookie 在服务器端数据库中识别用户特定的“购物篮”在他们自己的客户端购物篮中,并带有一个 URI,用于在客户准备购买时结帐。
我对他的用户偏好示例的理解如下。假设一个网站允许其用户在 URI /preferences(如 Stack Overflow)的首选项页面中选择浅色主题(默认)和深色主题。当用户选择深色主题时,他应该被重定向到 URI /preferences?theme=dark,其 HTML 表示形式将与 URI /preferences 的 HTML 表示形式相同,只是现在处于深色模式和查询 @987654327 @ 将附加到所有嵌入的超链接。这样,如果用户选择例如在 URI /home?theme=dark(不是/home)的主页的嵌入式超链接,那么主页的 HTML 表示也将处于暗模式,查询 ?theme=dark 也将附加到其所有嵌入的超链接。要恢复到轻主题,然后用户选择在 URI /preferences?theme=dark 处的首选项页面的嵌入超链接,在首选项页面中选择轻主题并应重定向到 URI /preferences,其 HTML 表示将与URI /preferences?theme=dark 的 HTML 表示,除了它现在将处于轻量模式并且查询 ?theme=dark 将从所有嵌入的超链接中删除。这是罗伊菲尔丁的意思吗?
对于他的购物车示例,当用户将产品 i 添加到购物车时,他应该被重定向到带有查询 ?product-{i}={product-i}&quantity-{i}={quantity-i} 的 URI,其 HTML 表示将把该查询附加到所有其嵌入的超链接。这样,当用户选择结帐超链接/checkout?product-1={product-1}&quantity-1={quantity-1}&…&product-n={product-n}&quantity-n={quantity-n}时,购物车的内容就会发送到网站。这是罗伊菲尔丁的意思吗?
【问题讨论】:
-
我没有读过菲尔丁的论文,也没有遵循那些引文中的推理,但是既然你(带外)让我看这个问题,我会说在我看来,主题之类的东西听起来像是两种不同的表示,例如机器可读 API 中的 JSON 与 XML。这些通常使用 HTTP 的内容协商协议而不是不同的 URL 来处理。毕竟,它们是同一资源的两种不同表示形式。
-
@MarkSeemann 感谢您的反馈。 content negotiation 的问题在于用户无法在 Web 浏览器中控制它。以及如何通过内容协商将用户选择保留在后续网页中?
-
我不确定我是否遵循。 REST 是一种机器可读 API 的设计理念。它们不应该被浏览器使用。例如,您不能使用浏览器发出
PUT或DELETE请求。 -
@MarkSeemann REST 实际上并不局限于机器可读的 API:'对我来说更重要的是相同的设计反映了良好的人类 Web 设计,因此我们可以设计协议来支持机器和','它需要知道的只是这些指令的含义以及它下一步想要做什么的一些想法,无论该目的是用户驱动的、配置驱动的还是某些有点人工智能驱动。'(参见 Roy Fielding 的 cmets here)。
-
@MarkSeemann 您实际上可以使用 Javascript 对象
XMLHttpRequest在浏览器中发送PUT或DELETEHTTP 请求。
标签: rest http cookies uri application-state