In the previous parts of this series, you learned what REST is, how to develop a RESTful application, and how to consume RESTful services. We’re getting close to the end now, and the only thing remaining is to discuss a little more about the protocol you’ll most likely use in any RESTful application that you write. Because HTTP is so often used with REST, that’s the protocol I’d like to focus on.
在本系列的前一部分中,您了解了REST是什么 , 如何开发 RESTful应用程序以及如何使用 RESTful服务。 我们现在快要结束了,剩下的唯一事情就是讨论更多有关您将在编写的任何RESTful应用程序中最有可能使用的协议的信息。 因为HTTP与REST经常一起使用,所以这就是我要关注的协议。
In a generic sense, I usually envision a single entity when I hear the word “header”, usually around 780 characters in length with about 50 parameters embedded in it where if you screw up one them up then whole thing doesn’t work. I also think of a header as being something that is set and proscribed by a standard. The standard specifies what values are sent with the header and you don’t have much control over the values or formatting. And there is generally only one header per transaction. But HTTP headers aren’t really like all of that.
从一般意义上讲,当听到“标题”一词时,我通常会设想一个实体,该实体通常约780个字符,其中嵌入了约50个参数,如果将它们拧紧,则整个对象将无法工作。 我还认为标头是由标准设置和禁止的标头。 该标准指定了与标头一起发送的值,您对这些值或格式没有太多控制权。 通常,每个事务只有一个标头。 但是HTTP标头并不是全部。
First, they tend to be very short.
首先,它们往往很短。
Second, every HTTP header contains only one characteristic (which is why they tend to be short).
其次,每个HTTP标头仅包含一个特征(这就是为什么它们往往很短的原因)。
Third, you will have multiple header lines, exactly how many depend on how much information you want to pass along with the request.
第三,您将有多个标题行,确切地说,多少行取决于您希望随请求传递的信息量。
In its simplest form, each header consists of two main things components: an identifier or characteristic, and a value, with a colon separating the two so there’s no hanky panky going on. There’s no semicolon to end the header but, as you’ll see in a few paragraphs, if you have more than one value for the identifier then the different values are separated by a semi-colon.
以最简单的形式,每个标头都由两个主要部分组成:一个标识符或特征,以及一个值,冒号将两者分开,因此不会产生麻烦。 在标头末尾没有分号,但是,正如您将在几段中看到的那样,如果标识符具有多个值,则不同的值将用分号分隔。
Here’s a couple of very simple HTTP headers to get your feet wet:
这是几个非常简单的HTTP标头,可以帮助您:
User-Agent: Safari 5.2 Accept: */*The first header one identifies the user agent (typically a web browser) that is making a request. The second indicates that when data is returned from the server, the user agent will accept all types of content. In both cases the specific characteristic is identified, followed by a colon, followed by the value you want it to have.
第一个标头标识正在发出请求的用户代理(通常是Web浏览器)。 第二个表示从服务器返回数据时,用户代理将接受所有类型的内容。 在这两种情况下,都将识别出特定的特征,然后是冒号,然后是您想要的特征值。
There are plethora of different headers that can be sent and received, and specifically which ones that will be used will depend on what your requirements are. Perhaps you will be the one who decides exactly which headers will be sent and what values will be attached to those headers… or perhaps you won’t care, much like the millions of people each day using a web browser.
可以发送和接收大量不同的标头,具体来说,将使用哪些标头取决于您的要求。 也许您将是一个确切地决定将发送哪些标头以及将哪些值附加到这些标头的人……或者您可能会不在乎,就像每天使用网络浏览器的数百万人一样。
But remember how I said “in its simplest form”? That should have been a very clear warning that things can get more complicated (or flexible), and indeed that is the case for most real-world usage.
但是还记得我怎么说“最简单的形式”? 这本来是一个非常明确的警告,警告说事情可能会变得更加复杂(或更加灵活),而实际上大多数实际情况都是如此。
Sometimes you may not want to just specify a single value for a characteristic. For example, consider the language a resource can be returned in. Maybe you prefer American English, but you’re a tolerant fellow accepting British English as well, and maybe Italian.
有时您可能不想只为特征指定一个值。 例如,考虑可以返回资源的语言。也许您更喜欢美式英语,但是您是一个宽容的人,也接受英式英语,也许也接受意大利语。
If you just wanted American English, then the Accept-Language header would be simple:
如果您只想使用美式英语,那么Accept-Language标头将很简单:
Accept-Language: en-usTo also accept British English and Italian, you use more complex notation, namely:
要也接受英式英语和意大利语,请使用更复杂的表示法,即:
Accept-Language: en-us; en-gb,q=0.8; it,q=0.3As I’ve already said, the colon separates the characteristic from its value. The semicolon separates multiple values from each other. Here q is a preference value that can ranging between 0 and 1 to give the server some sort of indication of how strongly you prefer one value over another. In the above example you’re requesting American English. But, if that is not available, you are willing to accept British English or Italian, but with a greater preference of British English over Italian if both are available.
正如我已经说过的,冒号将特征与价值分开。 分号将多个值彼此分开。 q是一个首选项值,范围在0到1之间,以向服务器提供某种指示,表明您相对于另一个值更喜欢一个值。 在上面的示例中,您需要美式英语。 但是,如果无法提供,则您愿意接受英式英语或意大利语,但如果英式和英式两种语言都可用,您会更喜欢英式英语。
There is always at least one header that will be present in a response, and that’s the status header. But unlike the format of the headers I’ve just explained, the status header is unique.
响应中始终至少有一个标头,即状态标头。 但是与我刚才解释的标头格式不同,状态标头是唯一的。
The status line consists of three pieces of information; the version of HTTP that was used, The three digit status code of the request, and a short description of what that status code means. For example,
状态行包括三部分信息: 使用的HTTP版本,请求的三位数状态代码以及该状态代码含义的简短描述。 例如,
HTTP/1.1 200 OKThere are quite a few values for the status code and a full set can be seen on Wikipedia. The basic breakdown of values however falls into the following classes.
状态码有很多值,全套可以在Wikipedia上看到 。 但是,值的基本分类分为以下几类。
1XX – Informational 1XX –信息性 2XX – Success 2XX –成功 3XX – Redirection 3XX –重定向 4XX – Client Error 4XX –客户端错误 5XX – Server Error 5XX –服务器错误Obviously, you want to keep a close eye on the status code and not just assume that everything is going to come back OK, just as you would check the return code on any program IO.
显然,您希望密切关注状态代码,而不仅仅是假设一切都会恢复正常,就像检查任何程序IO上的返回代码一样。
There are a large number of different headers that you can use, most with it’s own characteristic verbiage. For a full list of what these are, you can again check out Wikipedia which breaks them down into Request headers and Response headers. For even more detail, look at the HTTP 1.1 Standard. Some of the most common headers, as listed in the book PHP Master: Write Cutting-edge Code are:
您可以使用大量不同的标头,大多数标头都有自己的特色。 有关这些内容的完整列表,您可以再次查看Wikipedia ,将其分为Request标头和Response标头。 有关更多详细信息,请参阅HTTP 1.1 Standard 。 如《 PHP Master:编写前沿代码 》一书中列出的一些最常见的标头是:
Accept – the format the client wants the response to be in.
Accept -客户希望回复所采用的格式。
Accept-Language – languages that are acceptable for the response.
Accept-Language –响应可接受的语言。
Accept-Encoding – which encoding the client supports.
Accept-Encoding –客户端支持的编码。
Content-Type – format of the response.
Content-Type –响应的格式。
Content-Encoding – encoding of the response.
Content-Encoding –响应的编码。
Content-Language – language of the response.
Content-Language –响应语言。
Content-Length – the size of the response.
Content-Length –响应的大小。
Set-Cookie – cookie data included in the response for use later.
Set-Cookie –响应中包含的cookie数据,以备后用。
Cookie – cookie data from an earlier request being sent with this one.
Cookie –与此请求一起发送的来自较早请求的cookie数据。
Expires – when content will no longer be available.
Expires –内容不再可用时。
Authorization – access information for protected resources.
Authorization –访问受保护资源的信息。
While you’ll probably never use most of the headers, you should still familiarize yourself with the entire list. Sometimes knowledge is it’s own reward.
尽管您可能永远不会使用大多数标头,但您仍然应该熟悉整个列表。 有时知识就是它自己的奖励。
So what does all this have to do with PHP? Well, if you plan on doing anything worthwhile with REST using HTTP, you’ll probably want to be able to send and receive headers. First, let’s start with an outbound response from PHP.
那么,这一切与PHP有什么关系呢? 好吧,如果您打算使用HTTP使用REST做任何值得的事情,那么您可能希望能够发送和接收标头。 首先,让我们从PHP的出站响应开始。
It is imperative that headers be sent before the actual response. The reason is that headers are just plain text and there is no magic that would differentiate between the headers and response body if they were mingled. Its a gentlemen’s agreement that headers will be sent first and all but creatures with the blackest of hearts abide by this rule.
必须在实际响应之前发送标头。 原因是标题只是纯文本,没有任何魔术可以将标题和响应主体区分开来。 绅士同意,将首先发送标头,除了心中最黑的生物之外的所有生物都遵守此规则。
To send a header from PHP to the user agent you use the header() function. For example:
要将标头从PHP发送到用户代理,请使用header()函数。 例如:
<?php header("Content-Language: en-AU");It really is that simple, mate! The header is enclosed in quotes because it’s a string and slapped into the function’s parenthesis zone. Oh, and since its a PHP statement, there is a semicolon at the end.
真的很简单,伙计! 标头用引号括起来,因为它是一个字符串,并被插入函数的括号区域。 哦,由于它是PHP语句,所以结尾处有分号。
You can send whatever headers you feel like for whatever you want to tell the user agent that is getting back the response. Want to set a date/time after which the response should be treated as stale? Use an Expire header. Want to have the user agent interpret the response as a PNG image? Send a Content-Type header. You can send whatever and however many headers you like, just before to send them before the response body.
您可以发送任何您想告诉用户代理要返回响应的标题。 是否要设置一个日期/时间,之后应将其视为过期? 使用Expire标头。 是否希望用户代理将响应解释为PNG图像? 发送一个Content-Type标头。 您可以发送任何您喜欢的标题,无论发送多少标题,都可以在将它们发送到响应正文之前发送。
The headers you send with a request can be used to tell the server more about the resource you are looking for. Let’s take the following example: we have a RESTful resource, example.com/user/42 that contains basic information on someone. But do you want information returned as an XML document? Or maybe you want just the profile picture of the individual it represents? The Accept header can further refine the representation details of the resource.
您随请求发送的标头可用于告诉服务器更多有关您正在寻找的资源的信息。 让我们以下面的示例为例:我们有一个RESTful资源example.com/user/42 ,其中包含有关某人的基本信息。 但是,您是否希望将信息作为XML文档返回? 或者,也许您只想要它所代表的个人的头像? Accept标头可以进一步完善资源的表示细节。
<?php $uri = "http://example.com/user/42"; $ch = curl_init(); // request XML representation of user curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/xml")); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_GET, true); $xml = curl_exec ($ch); // request image representation of user curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: image/jpg")); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_GET, true); $jpg = curl_exec ($ch);The advantage that such headers give us is that we can create one resource, such as example.com/user/42, but have multiple ways to represent it without having to define multiple resources for each type (such as example.com/user/42.xml and example.com/user/42.html). This is a nice, RESTful approach that keeps the URI pure and takes full advantage of the protocol used.
这样的标头给我们带来的好处是我们可以创建一个资源,例如example.com/user/42 ,但是可以用多种方式表示它,而不必为每种类型定义多个资源(例如example.com/user/42.xml和example.com/user/42.html )。 这是一种很好的RESTful方法,可保持URI纯净并充分利用所使用的协议。
As you’ve seen, there are many HTTP headers already defined. And you would think that would be enough. But no, no amount of headers is ever enough for some people, and so HTTP also allows you to define your own custom headers.
如您所见,已经定义了许多HTTP标头。 而且您会认为就足够了。 但是,不行,对于某些人来说,没有足够的标头,因此HTTP还允许您定义自己的自定义标头。
What kind of thing might you put in a custom header? It could be almost anything. Maybe you want the location of the server to be returned to the client. To be honest, figuring out what you want that is not already in a standard header seems to be more your problem than mine. It’s almost midnight here and I think you really need to take some initiative here!
您可以在自定义标头中放入哪种内容? 几乎可以是任何东西。 也许您希望将服务器的位置返回给客户端。 坦白地说,弄清楚标准头文件中还没有的内容似乎比我的问题更多。 这里快到午夜了,我认为您真的需要在这里采取一些主动!
One thing you’ll want to keep in mind though is that you’ll still need to define the custom header within the context you are working in. That is, a custom header is in a sense like a local variable and will have meaning only within a certain space. Both the web server and the client need to agree its meaning in relation to the request.
不过,您需要牢记的一件事是,您仍然需要在正在使用的上下文中定义自定义标头。也就是说,自定义标头在某种意义上类似于局部变量,并且仅具有含义在一定的空间内。 Web服务器和客户端都需要就其请求达成一致。
Custom headers seem to be a bit controversial with some developers concerned about their proliferation because there are no real standard for them. Some people prefer prefixing the verbiage with “x-”, and others think it’s not a good idea in case such a custom header were to ever find its way into the standard.
自定义标头似乎对某些担心其扩散的开发人员有些争议,因为它们没有真正的标准。 有些人喜欢用“ x-”作为前缀,而另一些人则认为这不是一个好主意,以防这样的自定义标头找到了进入标准的方式。
So, custom headers are bad, right? Well, not necessarily. As it turns out some of the big players like Google and Oracle, have defined a set of their own customer headers that can be used with their REST APIs. So, maybe they aren’t the devil after all.
因此,自定义标头是不好的,对吧? 好吧,不一定。 事实证明,一些大型公司(例如Google和Oracle )已经定义了一套自己的客户标头,可以与他们的REST API一起使用。 因此,也许它们毕竟不是魔鬼。
As you can see, HTTP headers are swell, providing a great deal of information both to and from the server, and doing so in a simple format that is right to the point. And, these headers are easy to set up and use in PHP.
如您所见,HTTP标头膨胀了,提供了往返服务器的大量信息,并且以一种很简单的格式进行了处理。 而且,这些标头易于在PHP中设置和使用。
You see, I told you everything would work out for the best. Although, now that I think of it, I actually never said that. And, based on my life so far, the idea of everything working out for the best seems just plain silly. But no matter how you slice it, REST is a solid alternative for much of your web application building needs, and something that you owe it to yourself to understand. Thanks for joining me in this four-part series, and I hope now you know more about REST than just how to spell it.
您知道,我告诉过您一切都会变得最好。 虽然,考虑到这一点,我实际上从未这么说过。 而且,从我到目前为止的生活来看,一切正常的想法看起来简直是愚蠢的。 但是,无论如何分割,REST都是满足您大多数Web应用程序构建需求的可靠替代,并且您应该自己理解它。 感谢您加入这个由四部分组成的系列文章,我希望您现在对REST的了解更多,而不仅仅是如何拼写。
Image via littlesam / Shutterstock
图片来自littlesam / Shutterstock
翻译自: https://www.sitepoint.com/rest-can-you-do-more-than-spell-it-4/
相关资源:jdk-8u281-windows-x64.exe