我正在寻找一种在基于PHP的Web应用程序,数据库和CMS中将API围绕默认功能包装的方法。

我环顾四周,发现了几个“骨架”框架。 除了我的问题的答案外,还有Tonic ,我喜欢它是REST框架,因为它非常轻巧。

我最喜欢REST的原因在于它的简单性,并希望基于它创建一个API架构。 我正在努力了解基本原理,但尚未完全了解它。 因此,有很多问题。

1.我理解正确吗?

说我有一个资源“用户”。 我可以像这样设置许多URI:

/api/users     when called with GET, lists users
/api/users     when called with POST, creates user record
/api/users/1   when called with GET, shows user recordwhen called with PUT, updates user recordwhen called with DELETE, deletes user record

到目前为止,这是RESTful架构的正确表示吗?

2.我需要更多动词

从理论上讲,创建,更新和删除可能就足够了,但实际上,我将需要更多的动词。 我意识到这些东西可以嵌入到更新请求中,但是它们是可以具有特定返回码的特定动作,因此我不想将它们全部放入一个动作中。

在用户示例中想到的一些是:

activate_login
deactivate_login
change_password
add_credit

如何表达诸如RESTful URL体系结构中的动作?

我的直觉是对URL之类的GET调用

/api/users/1/activate_login

并期待返回状态码。

但是,这与使用HTTP动词的想法不同。 你怎么看?

3.如何返回错误消息和代码

REST之美的很大一部分源于其对标准HTTP方法的使用。 出现错误时,我发出带有3xx,4xx或5xx错误状态代码的标头。 有关错误的详细说明,我可以使用主体(对吗?)。 到现在为止还挺好。 但是,传输专有错误代码的方式将是什么呢?该错误代码会在描述错误原因(例如“连接数据库失败”或“数据库登录错误”)中进行更详细的说明? 如果将其与消息一起放入正文中,则必须在以后对其进行解析。 是否有用于此类事物的标准标头?

4.如何进行身份验证

  • 遵循REST原理的基于API密钥的身份验证会是什么样?
  • 除了对REST原则的公然违反之外,在验证REST客户端时是否有使用会话的强项? :)(在这里只是开个玩笑,基于会话的身份验证可以在我现有的基础架构中很好地发挥作用。)

#1楼

我建议(作为第一步) PUT仅应用于更新现有实体。 POST应该用于创建新的。 即

/api/users     when called with PUT, creates user record

我觉得不对。 但是,第一部分的其余部分(动词用法)看起来很合逻辑。


#2楼

  1. 当您不知道新资源URI的外观(创建新用户,应用程序将为新用户分配其ID)时使用post,使用PUT更新或创建您知道如何表示资源的资源(示例:PUT /myfiles/thisismynewfile.txt)
  2. 在消息正文中返回错误描述
  3. 您可以使用HTTP身份验证(如果足够的话),Web服务应该处于状态状态

#3楼

对于您说的示例,我将使用以下代码:

activate_login

POST /users/1/activation

deactivate_login

DELETE /users/1/activation

更改密码

PUT /passwords (这假设用户已通过身份验证)

add_credit

POST /credits (这假设用户已通过身份验证)

对于错误,您将以收到请求的格式在正文中返回错误,因此,如果收到:

DELETE /users/1.xml

您将以XML发送回响应,对于JSON等也是如此。

对于身份验证,您应该使用http身份验证。


#4楼

详细,但是从http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html的HTTP 1.1方法规范复制而来的

9.3获取

GET方法意味着检索由Request-URI标识的任何信息(以实体形式)。 如果Request-URI指的是数据产生过程,则应将产生的数据作为响应中的实体而不是过程的源文本作为实体返回,除非该文本恰好是过程的输出。

如果请求消息包含If-Modified-Since,If-Unmodified-Since,If-Match,If-None-Match或If-Range标头字段,则GET方法的语义将更改为“条件GET”。 条件GET方法仅在条件标头字段描述的情况下才请求转移实体。 有条件的GET方法旨在通过允许刷新缓存的实体而无需多个请求或传输客户端已经拥有的数据来减少不必要的网络使用。

如果请求消息包含Range标头字段,则GET方法的语义将更改为“部分GET”。 部分GET请求仅转移实体的一部分,如14.35节所述。 部分GET方法旨在通过允许部分取回的实体完成而无需传输客户端已经拥有的数据来减少不必要的网络使用。

且仅当满足GET请求的响应符合第13节中描述的HTTP缓存要求时,该响应才可以缓存。

有关用于表单的安全注意事项,请参阅第15.1.3节。

9.5开机自检

POST方法用于请求源服务器接受请求中包含的实体作为请求行中Request-URI标识的资源的新下属。 POST旨在允许采用统一的方法来覆盖以下功能:

  - Annotation of existing resources;- Posting a message to a bulletin board, newsgroup, mailing list,or similar group of articles;- Providing a block of data, such as the result of submitting aform, to a data-handling process;- Extending a database through an append operation.

POST方法执行的实际功能由服务器确定,通常取决于Request-URI。 发布的实体从属于该URI,其方式类似于文件从属于包含该实体的目录,新闻从属于其发布到的新闻组,或者记录从属于数据库。

POST方法执行的操作可能不会导致可以由URI标识的资源。 在这种情况下,适当的响应状态是200(确定)或204(无内容),这取决于响应是否包括描述结果的实体。

如果已经在原始服务器上创建了资源,则响应应该为201(已创建),并包含一个描述请求状态并引用新资源的实体以及一个Location头(参见14.30节)。

除非响应包含适当的Cache-Control或Expires标头字段,否则对此方法的响应不可缓存。 但是,303(请参阅其他)响应可用于指导用户代理检索可缓存的资源。

POST请求必须遵守第8.2节中规定的消息传输要求。

出于安全考虑,请参阅第15.1.3节。

9.6放置

PUT方法请求将封闭的实体存储在提供的Request-URI下。 如果Request-URI引用了已经存在的资源,则应将封闭的实体视为驻留在原始服务器上的实体的修改版本。 如果Request-URI没有指向现有资源,并且请求用户代理能够将该URI定义为新资源,则原始服务器可以使用该URI创建资源。 如果创建了新资源,则原始服务器务必通过201(已创建)响应通知用户代理。 如果修改了现有资源,则应发送200(确定)或204(无内容)响应代码以指示请求已成功完成。 如果无法使用Request-URI创建或修改资源,则应给出反映问题性质的适当错误响应。 实体的接收者不得忽略其无法理解或实现的任何Content-*(例如Content-Range)报头,并且在这种情况下必须返回501(未实现)响应。

如果请求通过缓存,并且Request-URI标识一个或多个当前缓存的实体,则应将这些条目视为过期。 此方法的响应不可缓存。

POST和PUT请求之间的根本区别体现在Request-URI的不同含义上。 POST请求中的URI标识将处理封闭实体的资源。 该资源可能是一个数据接受过程,某个其他协议的网关或一个接受注释的单独实体。 相比之下,PUT请求中的URI标识请求中包含的实体-用户代理知道要使用的URI,并且服务器绝不能尝试将请求应用于其他资源。 如果服务器希望将请求应用于其他URI,

它必须发送301(永久移动)响应; 然后,用户代理可以自行决定是否重定向请求。

单个资源可以由许多不同的URI标识。 例如,文章可能具有用于标识“当前版本”的URI,该URI与标识每个特定版本的URI分开。 在这种情况下,对通用URI的PUT请求可能会导致原始服务器定义其他几个URI。

HTTP / 1.1并未定义PUT方法如何影响原始服务器的状态。

PUT请求必须遵守第8.2节中规定的消息传输要求。

除非为特定的实体头另有规定,否则PUT请求中的实体头应该应用于由PUT创建或修改的资源。

9.7删除

DELETE方法请求原始服务器删除由Request-URI标识的资源。 在原始服务器上,人为干预(或其他方式)可能会覆盖此方法。 即使从原始服务器返回的状态代码指示该操作已成功完成,也不能保证客户机已执行了该操作。 但是,服务器不应指示成功,除非在给出响应时服务器打算删除资源或将其移动到无法访问的位置。

如果响应包含描述状态的实体,则成功响应应该为200(确定);如果尚未执行该操作,则为202(接受);如果已经执行该动作但响应不包括该响应,则返回204(无内容)。一个实体。

如果请求通过缓存,并且Request-URI标识一个或多个当前缓存的实体,则应将这些条目视为过期。 此方法的响应不可缓存。


#5楼

关于1 :到目前为止看起来还不错。 切记在“ Location:”标头中返回新创建的用户的URI,作为对POST响应的一部分,并返回“ 201 Created”状态代码。

关于2 :通过GET激活不是一个好主意,在URI中包含动词是一种设计气味。 您可能要考虑在GET上返回表单。 在Web应用程序中,这将是带有提交按钮的HTML表单。 在API用例中,您可能需要向PUT返回包含URI的表示形式以激活帐户。 当然,您也可以在对/ users的POST响应中包含此URI。 使用PUT将确保您的请求是幂等的,即,如果客户端不确定成功是否可以安全地再次发送。 通常,考虑一下可以将动词转化为哪些资源(一种“动词名词化”)。 问问自己,您的特定动作最接近于哪种方法。 例如change_password-> PUT; 停用->可能是DELETE; add_credit->可能是POST或PUT。 通过将客户端包括在您的表示中,将其指向适当的URI。

关于3.不要发明新的状态码,除非您认为它们是如此通用,所以值得在全球范围内进行标准化。 尝试使用可用的最合适的状态代码(有关详细信息,请参阅RFC 2616)。 在响应正文中包括其他信息。 如果您真的确定要发明一个新的状态码,请再考虑一遍。 如果仍然相信,请确保至少选择正确的类别(1xx->确定,2xx->信息,3xx->重定向; 4xx->客户端错误,5xx->服务器错误)。 我是否提到发明新的状态代码是一个坏主意?

4.如果可能,请使用HTTP内置的身份验证框架。 了解Google在GData中进行身份验证的方式。 通常,请勿将API密钥放在您的URI中。 尝试避免使用会话来增强可伸缩性并支持缓存-如果由于以前发生的事情而导致对请求的响应有所不同,则通常会将自己绑定到特定的服务器流程实例。 最好将会话状态转换为客户端状态(例如,使其成为后续请求的一部分)或通过将其转换为(服务器)资源状态(即为其提供自己的URI)来使其显式。


#6楼

1.恕我直言,您对如何设计资源有正确的想法。 我不会改变任何事情。

2.不要尝试用更多的动词来扩展HTTP,而是考虑可以根据基本的HTTP方法和资源将建议的动词简化为什么。 例如,您可以设置资源,例如: /api/users/1/login/active ,而不是activate_login动词,它是一个简单的布尔值。 要激活登录,只需PUT文件那里,说“真”或1或别的什么东西。 要停用此功能,请在该文件中PUT空白或为0或false的文档。

同样,要更改或设置密码,只需对/api/users/1/password进行PUT即可。

每当您需要添加某些内容(例如信用)时,请考虑POST 。 例如,您可以对包含/api/users/1/credits类的资源执行POST ,其正文包含要添加的积分数。 可以使用同一资源上的PUT覆盖值而不是添加值。 正文中带有负数的POST将减去,依此类推。

3.我强烈建议不要扩展基本的HTTP状态代码。 如果找不到与您的情况完全匹配的解决方案,请选择最接近的一种,并将错误详细信息放入响应正文中。 另外,请记住,HTTP标头是可扩展的。 您的应用程序可以定义您喜欢的所有自定义标头。 例如,我处理过的一个应用程序可能在多种情况下返回404 Not Found 。 我们没有添加客户端解析原因的理由,而是添加了新的标头X-Status-Extended ,其中包含我们专有的状态码扩展。 因此,您可能会看到如下响应:

HTTP/1.1 404 Not Found
X-Status-Extended: 404.3 More Specific Error Here

这样,像Web浏览器这样的HTTP客户端仍将知道如何处理常规404代码,而更复杂的HTTP客户端可以选择查看X-Status-Extended标头以获取更多特定信息。

4.对于身份验证,建议您尽可能使用HTTP身份验证。 但是恕我直言,使用基于cookie的身份验证对您来说没有任何问题。


#7楼

我几天后才注意到这个问题,但我觉得我可以补充一些见识。 我希望这可以对您的RESTful事业有所帮助。


第一点:我理解正确吗?

你说的没错。 这是RESTful架构的正确表示。 您可能会发现Wikipedia中的以下矩阵对于定义名词和动词非常有帮助:


当与集合 URI就像对付: http://example.com/resources/

  • GET :列出集合的成员,并带有其成员URI以便进一步导航。 例如,列出所有待售汽车。

  • PUT :定义为“将整个集合替换为另一个集合”。

  • POST :在集合中创建一个新条目,其中ID由集合自动分配。 创建的ID通常包含在此操作返回的数据中。

  • DELETE :定义为“删除整个集合”的含义。


处理类似以下成员的 URI时: http://example.com/resources/7HOU57Y : http://example.com/resources/7HOU57Y

  • GET :检索以适当的MIME类型表示的集合中所寻址成员的表示形式。

  • PUT :更新集合的寻址成员或使用指定的ID创建它。

  • POST :将被寻址成员本身视为一个集合,并为其创建新的下属。

  • DELETE :删除集合中寻址的成员。


第二点:我需要更多动词

通常,当您认为您需要更多的动词时,实际上可能意味着您的资源需要重新标识。 请记住,在REST中,您总是在作用于资源或资源的集合。 您选择的资源对于您的API定义非常重要。

激活/停用登录 :如果要创建新会话,则可能需要将“会话”视为资源。 要创建新会话,请使用正文中的凭据使用POST到http://example.com/sessions/ 。 要使其过期,请使用PUT或DELETE(可能取决于您是否要保留会话历史记录)到http://example.com/sessions/SESSION_ID

更改密码:这次资源是“用户”。 您需要使用正文中的旧密码和新密码对http://example.com/users/USER_ID进行PUT操作。 您正在使用“用户”资源,更改密码只是一个更新请求。 它与关系数据库中的UPDATE语句非常相似。

我的直觉是要对/api/users/1/activate_login类的URL进行GET调用

这违反了一个非常核心的REST原则:HTTP动词的正确用法。 任何GET请求都不应留下任何副作用。

例如,GET请求永远不要在数据库上创建会话,返回具有新会话ID的cookie或在服务器上保留任何残差。 GET动词类似于数据库引擎中的SELECT语句。 请记住,使用相同的参数请求时,使用GET动词对任何请求的响应都应该是可缓存的,就像您请求静态网页一样。


第3点:如何返回错误消息和代码

将4xx或5xx HTTP状态代码视为错误类别。 您可以在正文中详细说明错误。

无法连接到数据库: / 错误的数据库登录 :对于这些类型的错误,通常应使用500错误。 这是服务器端错误。 客户没有做错任何事。 通常将500个错误视为“可重试”。 也就是说,客户端可以重试相同的确切请求,并期望一旦服务器的问题解决,请求就会成功。 在正文中指定详细信息,以便客户可以向我们的工作人员提供一些背景信息。

错误的另一类是4xx系列,通常表示客户端做错了什么。 尤其是,此类错误通常会向客户端指示无需按原样重试请求,因为它将继续永久失败。 也就是说,客户端需要在重试此请求之前进行一些更改。 例如,“找不到资源”(HTTP 404)或“格式错误的请求”(HTTP 400)错误将属于此类别。


要点4:如何进行身份验证

正如第1点所指出的,您可能需要考虑创建会话,而不是对用户进行身份验证。 您将获得一个新的“会话ID”以及相应的HTTP状态代码(200:已授予访问权限或403:已拒绝访问)。

然后,您将问您的RESTful服务器:“您能为我获取此会话ID的资源吗?”。

没有身份验证模式-REST是无状态的:创建会话,要求服务器使用此会话ID作为参数为您提供资源,并在注销时删除或终止该会话。


#8楼

简而言之,您正在完全落后。

您不应该从应该使用的URL处获取信息。 一旦您确定了系统所需的资源以及如何表示这些资源以及资源与应用程序状态之间的交互,这些URL将有效地“免费”出现。

引用罗伊·菲尔丁(Roy Fielding)

REST API应该花费几乎所有的描述性精力来定义用于表示资源和驱动应用程序状态的媒体类型,或者为现有标准媒体类型定义扩展的关系名称和/或启用超文本的标记。 花费所有精力描述应该在媒体类型的处理规则范围内(并且在大多数情况下已由现有媒体类型定义)完全定义要在感兴趣的URI上使用的方法。 [此处的失败表示带外信息正在驱动交互,而不是超文本。

人们总是以URI开头,并认为这是解决方案,然后他们往往会错过REST体系结构中的一个关键概念,特别是,如上文所述,“此处的失败表示带外信息正在推动交互而非超文本。 ”

老实说,许多人看到了很多URI以及一些GET,PUT和POST,并认为REST很容易。 REST并不容易。 通过HTTP进行RPC很容易,通过HTTP有效负载来回移动数据块很容易。 REST不仅如此。 REST与协议无关。 HTTP只是非常流行,并且适用于REST系统。

REST存在于媒体类型,它们的定义以及应用程序如何通过超文本(有效地链接)来驱动那些资源可用的操作中。

关于REST系统中的媒体类型有不同的看法。 一些支持特定于应用程序的有效负载,而另一些支持将现有媒体类型提升为适合该应用程序的角色。 例如,一方面,您已经设计了适合您的应用程序的特定XML模式,而不是通过微格式和其他机制使用诸如XHTML的表示形式。

我认为,这两种方法在XHTML都可以很好地与人为驱动和机器驱动的Web重叠的情况下都能很好地发挥作用,而我认为前者更具体的数据类型更好地促进了人机交互。 我发现商品格式的提升可能会使内容协商变得困难。 “ application / xml + yourresource”作为媒体类型比“ application / xhtml + xml”更具体,因为后者可以应用于许多有效负载,这些负载可能是机器客户端真正感兴趣的,也可能不是无需内省即可确定。

但是,XHTML在Web上的浏览器和呈现非常重要的人类网络中(显然)工作得很好。

您的应用程序将指导您进行此类决策。

设计REST系统的过程的一部分是发现系统中的一流资源以及派生的支持资源,以支持对主要资源的操作。 一旦发现资源,这些资源的表示形式以及由于下一个挑战而通过表示形式中的超文本显示资源流的状态图。

回想一下,在超文本系统中,资源的每种表示形式都将实际的资源表示形式与资源可用的状态转换结合在一起。 将每个资源视为图中的一个节点,链接是使该节点保持其他状态的线。 这些链接不仅通知客户端可以做什么,而且还通知客户端要完成它们所需的操作(因为良好的链接结合了URI和所需的媒体类型)。

例如,您可能有:

<link href="http://example.com/users" rel="users" type="application/xml+usercollection"/>
<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>

您的文档将讨论名为“ users”的rel字段,以及“ application / xml + youruser”的媒体类型。

这些链接似乎是多余的,它们几乎都在使用相同的URI。 但事实并非如此。

这是因为对于“用户”关系,该链接所讨论的是用户集合,并且您可以使用统一界面来处理用户集合(GET检索所有用户,DELETE删除所有用户,等等)。

如果您发布到该URL,则需要传递“ application / xml + usercollection”文档,该文档可能仅包含一个用户实例,因此您可以添加该用户,也可以不添加该用户,例如一旦。 也许您的文档会建议您只传递一个用户类型,而不是集合。

您可以查看应用程序执行搜索所需要的内容,如“搜索”链接及其媒体类型所定义。 搜索媒体类型的文档将告诉您它的行为方式以及预期结果。

不过,这里的要点是URI本身基本上并不重要。 该应用程序控制URI,而不控制客户端。 除了一些“入口点”,您的客户还应依靠应用程序提供的URI进行工作。

客户需要知道如何操纵和解释媒体类型,但是并不需要关心它的去向。

在客户看来,以下两个链接在语义上是相同的:

<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>
<link href="http://example.com/AW163FH87SGV" rel="search" type="application/xml+usersearchcriteria"/>

因此,请专注于您的资源。 专注于他们在应用程序中的状态转换以及如何最好地实现。


#9楼

REST基础

REST具有统一的接口约束,该约束指出REST客户端必须依赖于标准,而不是实际REST服务的应用程序特定细节,因此REST客户端不会受到较小的更改,并且可以重用。

因此,REST客户端与REST服务之间存在合同。 如果您使用HTTP作为基础协议,那么以下标准是合同的一部分:

  • HTTP 1.1

    • 方法定义
    • 状态码定义
    • 缓存控制标头
    • 接受和内容类型标题
    • auth头
  • IRI (utf8 URI )
  • 身体(一个)
    • 注册的应用程序特定的MIME类型,例如maze + xml
    • 供应商特定的MIME类型,例如vnd.github + json
    • 通用MIME类型,带有
      • 特定于应用程序的RDF vocab,例如ld + json & hydra , schema.org
      • 特定于应用程序的配置文件,例如hal + json和配置文件链接参数(我想)
  • 超连结
    • 应该包含什么(选择一个)

      • 发送链接头
      • 发送超媒体响应,例如html,atom + xml,hal + json,ld + json&hydra等...
    • 语义学
      • 使用IANA链接关系以及可能的自定义链接关系
      • 使用特定于应用程序的RDF vocab

REST具有无状态约束,该约束声明REST服务与客户端之间的通信必须是无状态的。 这意味着REST服务无法维护客户端状态,因此您不能拥有服务器端会话存储。 您必须对每个请求进行身份验证。 因此,例如HTTP基本身份验证(HTTP标准的一部分)是可以的,因为它随每个请求发送用户名和密码。

回答你的问题

  1. 是的,可以。

    只需提及,客户端并不关心IRI结构,而是关心语义,因为它们遵循具有链接关系或链接数据(RDF)属性的链接。

    关于IRI唯一重要的事情是,单个IRI必须仅标识单个资源。 允许单个资源(如用户)具有许多不同的IRI。

    很简单,为什么我们使用漂亮的IRI,如/users/123/password ; 当您仅通过阅读IRI来理解IRI时,在服务器上编写路由逻辑就容易得多。

  2. 您有更多的动词,例如PUT,PATCH,OPTIONS甚至更多,但您并不需要更多...除了添加新的动词,您还必须学习如何添加新的资源。

    activate_login -> PUT /login/active true deactivate_login -> PUT /login/active false change_password -> PUT /user/xy/password "newpass" add_credit -> POST /credit/raise {details: {}}

    (由于无状态限制,从REST角度看,登录没有意义。)

  3. 您的用户不关心问题存在的原因。 他们只想知道是成功还是出错,可能想知道一条错误消息,例如:“抱歉,我们无法保存您的帖子。”,等等。

    HTTP状态标头是您的标准标头。 我认为其他一切都应该在体内。 单个标头不足以描述例如详细的多语言错误消息。

  4. 无状态约束(以及缓存和分层系统约束)可确保服务扩展良好。 当您可以在客户端上执行相同的操作时,您肯定不会在服务器上维护数百万个会话。

    如果用户使用主客户端授予访问令牌,则第三方客户端将获得访问令牌。 之后,第三方客户端将随每个请求一起发送访问令牌。 有更复杂的解决方案,例如您可以签署每个请求等。有关更多详细信息,请参阅OAuth手册。

相关文献

  • 架构风格和基于网络的软件架构设计
    Roy Thomas Fielding的论文(REST的作者)
    2000年,加州大学尔湾分校
  • 第三代Web API-缩小REST和链接数据之间的差距
    Markus Lanthaler的论文(JSON-LD的合著者和Hydra的作者)
    2014年,奥地利格拉茨工业大学

#10楼

关于REST返回码:混合使用HTTP协议代码和REST结果是错误的

但是,我看到许多实现混在一起,许多开发人员可能不同意我的看法。

HTTP返回码与HTTP Request本身有关。 REST调用是使用超文本传输​​协议请求完成的,并且其工作级别比调用的REST方法本身低。 REST是一种概念/方法,其输出是业务/逻辑结果,而HTTP结果代码是一种传输结果。

例如,在调用/ users /时返回“ 404 Not found”很容易混淆,因为这可能意味着:

  • URI错误(HTTP)
  • 找不到用户(REST)

“ 403禁止/拒绝访问”可能表示:

  • 需要特殊许可。 浏览器可以通过询问用户/密码来处理它。 (HTTP)
  • 服务器上配置的访问权限错误。 (HTTP)
  • 您需要通过身份验证(REST)

并且该列表可能会继续显示“ 500服务器错误”(Apache / Nginx HTTP抛出错误或REST中的业务约束错误)或其他HTTP错误等。

从代码中,很难理解什么是失败原因,HTTP(传输)失败或REST(逻辑)失败。

如果HTTP请求实际上已成功执行,则无论是否找到记录,它都应始终返回200代码。 因为找到 URI资源并由http服务器处理。 是的,它可能会返回一个空集。 是否可能会收到一个空页面,显示http结果为200,对吗?

取而代之的是,您可以返回200个HTTP代码以及一个带有空数组/对象的JSON,或者使用bool结果/成功标志来告知已执行的操作状态。

此外,某些互联网提供商可能会拦截您的请求并返回404 http代码。 这并不意味着未找到您的数据,但是在传输级别是有问题的。

从维基 :

2004年7月,英国电信提供商BT Group部署了Cleanfeed内容阻止系统,该程序将对Internet Watch Foundation认定为潜在违法的任何内容请求返回404错误。 在相同的情况下,其他ISP返回HTTP 403“禁止”错误。 在泰国和突尼斯,也有使用伪造的404错误作为掩盖审查制度的方法的报道。 在突尼斯,2011年革命之前审查制度很严厉,人们开始意识到伪造的404错误的性质,并创建了一个假想的人物,名为“ Ammar 404”,代表“无形的审查者”。

了解REST:动词,错误代码和身份验证相关推荐

  1. WIN10远程桌面连接发生身份验证错误(错误代码:0x800706be)

    问题: 今天在用远程桌面连接服务器的时候突然报错,说是身份验证错误,代码: 0x800706be.如下图所示: 网上也搜了很多办法都没能成功,后来用以下这个办法解决了,如下所示: 解决办法: ①.第一 ...

  2. 远程桌面连接发生身份验证错误(错误代码:0x800706be)

    问题:在Windows10中,远程连接问题发生身份验证错误(代码:0x800706be),具体如下图. 问题原因:通常是无线外接蓝牙接收器的驱动中的一个dll文件导致的,具体引起机制不明,请高手分析. ...

  3. java ldap操作实例_Java Spring Security示例教程中的2种设置LDAP Active Directory身份验证的方法...

    java ldap操作实例 LDAP身份验证是世界上最流行的企业应用程序身份验证机制之一,而Active Directory (Microsoft为Windows提供的LDAP实现)是另一种广泛使用的 ...

  4. Java Spring Security示例教程中的2种设置LDAP Active Directory身份验证的方法

    LDAP身份验证是全球范围内最流行的企业应用程序身份验证机制之一,而Active Directory (Microsoft针对Windows的LDAP实现)是另一种广泛使用的LDAP服务器. 在许多项 ...

  5. idea中使用osgi_OSGi环境中的Servlet基本身份验证

    idea中使用osgi 您首先需要获得对OSGI HTTP Service的引用. 您可以通过声明性服务来做到这一点. 这篇文章将集中在获得对HTTP服务的引用之后的步骤. 注意:此职位的完整课程位于 ...

  6. OSGi环境中的Servlet基本身份验证

    您首先需要获得对OSGI HTTP Service的引用. 您可以通过声明性服务来做到这一点. 这篇文章将集中在获得对HTTP服务的引用之后的步骤. 注意:此职位的完整课程位于此处 通过OSGI HT ...

  7. 微软SQL服务器登录,Microsoft SQL Server 【Windows 身份验证】和 【sa】都无法登录的解决方案...

    1.修改启动参数:打开[SQL Server 配置管理器(SQL Server Configuration Manager)]→右键[SQL Server(MSSQLSERVER)]属性→高级(Adv ...

  8. RFC8705-OAuth 2.0双向TLS客户端身份验证和证书绑定访问令牌

    RFC8705-OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens 目录 摘要 1. 简介(I ...

  9. Vue之jwt(跨域身份验证,令牌)

    1. JWT是什么 JSON Web Token (JWT),它是目前最流行的跨域身份验证解决方案 2. 为什么使用JWT JWT的精髓在于:"去中心化",数据是保存在客户端的. ...

最新文章

  1. web app升级—带进度条的App自动更新
  2. 【Qt】Linux上设置自启动后qApp->applicationDirPath()的返回值问题
  3. Qt irrlicht(鬼火)3D引擎 摄像机旋转问题
  4. Docker Review - 图形化工具 Portainer
  5. 分类器评价与在R中的实现:混淆矩阵
  6. js碎片知识的学习与补充(parseint与ChildNodes属性)
  7. 巧用计算机辅助培智生,计算机辅助设计答案
  8. 利用jquery实现数字千分位排版显示,使用0动态补全8位数
  9. JAVA连接数据库 遍历集合数组!!!
  10. day16 Python 类的继承关系
  11. 工控蜜罐 Conpot 的进阶玩法
  12. IntelliJ IDEA如何创建Source Folder和导入jar包
  13. 至强服务器性能视频,至强CPU性能表现测试
  14. php strpos 编码问题,PHP代码审计04之strpos函数使用不当
  15. 数据结构 第14讲 神秘电报密码——哈夫曼编码
  16. 1、蛋白质二级结构预测方法
  17. 为什么技术开发者应该读一读《浪潮之巅》
  18. win10无法装载iso文件_Win10系统怎么安装iso镜像文件 Win10系统安装iso镜像文件方法...
  19. 谷歌浏览器打开之后显示2345
  20. 计算机表格大小怎么调整,excel把表格拉大_excel调整单元格大小的方法步骤详解...

热门文章

  1. 3G应用需要所有的网友共同创造
  2. Linux桌面版横评:一、评测背景
  3. 生成模型和判别模型直接的区别
  4. vue2.0环境搭建
  5. CF-697B Barnicle与691C Exponential notation
  6. bzoj1854 [Scoi2010]游戏
  7. 继承(引用~析构~virtual)
  8. 一款C++ 可视化调试工具增强插件
  9. 判断客户端是否安装FlashPlayer及版本
  10. C#数据库类(zz)