选项在 REST API 调用之前调用元

Posted

技术标签:

【中文标题】选项在 REST API 调用之前调用元【英文标题】:Options call for meta before REST API call 【发布时间】:2016-11-12 20:56:53 【问题描述】:

我试图了解这个系统是如何在幕后工作的。该系统基于REST,这是非常标准的,我没有得到客户端在每次API调用之前调用OPTIONS并以格式返回xml内容。它使用的是 Jersey Java。

OPTIONSDELETE 方法的响应

Access-Control-Request-Method: DELETE 在标头中传递

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
    <doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 2.8 2014-04-29 01:25:26"/>
    <grammars/>
    <resources base=“http://domain.com”>
        <resource path=“data/gasdfasdg/entity”>
            <method id="deleteEntity" name="DELETE">
                <request>
                    <param xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string"/>
                </request>
                <response>
                    <representation mediaType="application/json"/>
                </response>
            </method>
            <method id="getOneEntitysMetadata" name="GET">
                <request>
                    <param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="q" style="query" type="xs:string"/>
                    <param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="x-dps-compute-content-size" style="header" type="xs:boolean"/>
                    <param xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string"/>
                </request>
                <response>
                    <representation mediaType="application/json"/>
                </response>
            </method>
            <method id="createOrUpdateEntity" name="PUT">
                <request>
                    <param xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string"/>
                </request>
                <response>
                    <representation mediaType="application/json"/>
                </response>
            </method>
        </resource>
    </resources>
</application>

问题

A.客户端首先调用OPTIONS,在进行实际调用之前处理和分析响应并确定API、参数等是标准还是行业惯例?早些时候,我一直在查看文档并相应地在客户端 (javascript) 中编写我的 REST 调用。

B.这个调用是由浏览器自动进行的(预检)还是在客户端编程?

【问题讨论】:

【参考方案1】:

要了解发生了什么,您需要了解CORS (cross origin resource sharing)。 OPTIONS 请求是 pre-flight 请求(由浏览器发出,以响应客户端尝试发出跨域 ajax 请求),这是对服务器的初始请求,以检查是否存在客户端被允许向服务器发出请求。飞行前请求发送服务器理解的特定标头,服务器将使用不同的标头进行响应。例如,客户端可能会发送

Origin: http://foo.example
Access-Control-Request-Method: DELETE

有了这两个请求头,就有了浏览器期望的两个对应的响应头。请求标头基本上是在询问“是否允许此来源”和“是否允许此方法”。服务器应该响应

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE

以上是响应头,表示允许来源,并且允许那些方法。如果您没有看到这些标头,则意味着您的服务器上没有配置 CORS。如果浏览器没有看到这些响应头,它就不会发出实际的请求。要配置 CORS,通常使用简单的过滤器。一些容器,比如 Tomcat 和 Jetty,有一个简单的过滤器实现,你可以配置,或者你可以自己动手,for example。

请注意,上述情况通常仅适用于浏览器和XmlHTTPRequest 请求,如以上链接所述。

XML 是WADL。你得到这个的唯一原因是因为 Jersey 默认启用了它自己的 WADL 功能。 WADL 不是强制性的,但 Jersey 有它,它被配置为响应 OPTIONS 请求。如果您禁用了 WADL(这是可能的),而不是获取 XML,您只会得到 405 Not Allowed 响应,这意味着该端点不允许使用 OPTIONS 方法。 WADL 与 CORS 协议无关。这只是 Jersey 的 WADL 功能的副作用。 WADL 和 CORS 没有任何关系。

【讨论】:

谢谢,WADL 似乎是一种标准,如果我正在为我的客户开发符合 REST 的服务,我应该提供 WADL 吗? 你没有。不过拥有它并没有什么坏处。 关于我链接到的 Jersey CORS 过滤器需要注意的一点是,它不是一个很好的实现。它甚至不是一个 正确的 实现(我将不得不在这些天更新答案:-)。对于 CORS 协议,飞行前响应应该是 200 状态,不返回正文。更好的过滤器实现方式是同时使用 request 过滤器 response 过滤器。请求过滤器将检查它是否是带有 Origin 标头的 OPTIONS 请求。如果是,则以 200 状态中止请求。响应过滤器仍将被称为添加标头 使用此实现,WADL 将永远不会被发送。这是应该发生的。为飞行前请求发送 XML 是浪费带宽。 在请求过滤器(ContainerRequesFilter)中,你可以做requestContext.abortWith(Response.ok().build())。这将中止请求,但仍会调用响应过滤器,添加响应标头。

以上是关于选项在 REST API 调用之前调用元的主要内容,如果未能解决你的问题,请参考以下文章

CakePHP 3 REST API + CORS 请求和选项方法

IBM ACE(新)- 调用在 WADL 或 API 中定义的 Rest API,没有 swagger 定义

每个选择选项的反应 API 调用

Django Form 将 ChoiceField 选项设置为 Form 被调用

用户选择后的API调用

keycloak 基于 JavaScript 的策略可以调用远程 REST API 吗?