이 기사에서는 주로 HTTP 요청 헤더 및 요청 본문에 대한 자세한 설명을 공유합니다. HTTP 연구에는 주로 HTTP 기본, HTTP 요청 헤더 및 요청 본문, HTTP 응답 헤더 및 상태 코드, HTTP 캐시의 네 부분이 포함됩니다. HTTP 관련 확장 더 나아가 HTTPS, HTTP/2 기본 및 WebSocket 기본에 대한 이해와 실습도 이해해야 합니다. 이 부분의 지식 포인트는 웹 프런트 엔드에서 서버 측 애플리케이션 아키텍처까지 학교 채용 준비 과정에 대한 저자의 리뷰에도 요약되어 있습니다.
HTTP 요청
HTTP 요청 메시지는 요청 라인, 요청 헤더, 요청 본문의 세 부분으로 나뉩니다. 형식은 그림과 같습니다.
일반적인 요청 메시지 헤더 필드는 다음과 같습니다.
POST/GET http://download.microtool.de:80/somedata.exe Host: download.microtool.de Accept:*/* Pragma: no-cache Cache-Control: no-cache Referer: http://download.microtool.de/ User-Agent:Mozilla/4.04[en](Win95;I;Nav) Range:bytes=554554-
요청 라인(요청 라인)은 요청 방법, 요청 주소, 프로토콜 및 버전의 세 부분으로 나뉘며 CRLF(rn)로 끝납니다.
HTTP/1.1은 GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE의 8가지 요청 방법을 정의합니다. 가장 일반적인 두 가지는 RESTful 인터페이스인 경우 GET, POST, DELETE, PUT입니다.
POST, PUT, PATCH 세 동사에만 요청 본문이 포함되고, GET, HEAD, DELETE, CONNECT, TRACE 및 OPTIONS 동사에는 요청 본문이 포함되지 않습니다.
Header | Explanation | Example |
---|---|---|
Accept | 클라이언트가 수신할 수 있는 콘텐츠 유형 지정 | Accept: text/plain, text/html, application/json |
Accept-Charset | 브라우저가 허용할 수 있는 문자 인코딩 집합입니다. | Accept-Charset: iso-8859-5 |
Accept-Encoding | 브라우저가 지원할 수 있는 웹 서버에서 반환한 콘텐츠 압축 인코딩 유형을 지정합니다. | Accept-Encoding: 압축, gzip |
Accept-Language | Accept-Language: en,zh | |
하나 이상의 웹 페이지 엔터티를 요청할 수 있습니다. 하위 범위 필드 | Accept -범위: 바이트 | |
HTTP 인증에 대한 인증 인증서 | 인증: 기본 QWxhZGRpbjpvcGVuIHNlc2FtZQ== | |
요청 및 응답에 따른 캐싱 메커니즘 지정 | 캐시 -제어: 아니요- 캐시 | |
은 지속적인 연결이 필요한지 여부를 나타냅니다. (HTTP 1.1은 기본적으로 영구 연결을 사용합니다.) | Connection: close | |
HTTP 요청이 전송되면 요청한 도메인 이름에 저장된 모든 쿠키 값이 웹 서버로 전송됩니다. | Cookie: $Version=1; Skin=new; | |
Content-Length | 요청된 콘텐츠 길이 | Content-Length: 348 |
Content-Type | 엔터티에 해당하는 요청된 MIME 정보 | Content-Type: application/x-www-form-urlencoded |
Date | 요청이 전송된 날짜 및 시간 | Date: 2010년 11월 15일 화요일 08:12:31 GMT |
Expect | 요청된 특정 서버 동작 | 예상: 100-continue |
From | 요청한 사용자의 이메일 | From: user@email.com |
Host | 도메인 이름과 포트를 지정하세요. 요청한 서버 번호 | Host: www.zcmhi.com |
If-Match | 요청 내용이 엔터티와 일치하는 경우에만 유효합니다. | If-Match: "737060cd8c284d8af7ad3082f209582d" |
If-수정-이후 | 요청한 경우 지정된 시간 이후에 부품이 수정되면 요청이 성공합니다. 수정되지 않은 경우 내용이 변경되지 않은 경우 304 코드가 반환됩니다. 이전에 서버에서 전송한 Etag를 서버에서 응답한 Etag와 비교하여 변경되었는지 확인합니다. 클라이언트의 누락된 부분을 보내고, 그렇지 않으면 전체 엔터티를 보냅니다.매개변수도 Etag | If-Range: "737060cd8c284d8af7ad3082f209582d" |
If-Unmodified-Since | 요청은 지정된 시간 이후에 엔터티가 수정되지 않은 경우에만 성공합니다 | If-Unmodified-Since: Sat , 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 정보가 프록시 및 게이트웨이를 통해 전송되는 시간을 제한하세요 | Max-Forwards: 10 |
Pragma | 구현 관련 내용을 포함하는 데 사용됩니다. 지침 | Pragma: no -cache |
Proxy-Authorization | 프록시에 연결된 인증 인증서 | Proxy-Authorization: 기본 QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 엔티티의 일부만 요청하고, range | Range: bytes=500- 999 |
Referer | 이전 웹페이지 주소, 현재 요청된 웹페이지 바로 뒤, 즉 오는 경로 | Referer: http://www.zcmhi. com/archives... |
TE | Customer 클라이언트가 수락할 전송 인코딩이며, 테일과 헤더 정보를 수락하도록 서버에 알립니다. | TE: trails,deflate;q=0.5 |
업그레이드 | 서버에서 변환할 수 있도록 특정 전송 프로토콜을 서버에 지정합니다(지원되는 경우) | 업그레이드: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | The User-Agent의 내용에는 요청한 사용자 정보가 포함되어 있습니다 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 중간 게이트웨이 또는 프록시 서버 주소, 통신 프로토콜 알림 | Via: 1.0 fred, 1.1where.com(Apache/1.1) |
Warning | 메시지 엔터티에 대한 경고 정보 | 경고: 199 기타 경고 |
根据应用场景的不同,HTTP请求的请求体有三种不同的形式。
移动开发者常见的,请求体是任意类型,服务器不会解析请求体,请求体的处理需要自己解析,如 POST JSON时候就是这类。
application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。
JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。
Google 的 AngularJS 中的 Ajax 功能,默认就是提交 JSON 字符串。例如下面这段代码:
JSvar data = {'title':'test', 'sub' : [1,2,3]};$http.post(url, data).success(function(result) { ... });
最终发送的请求是:
BASHPOST http://www.example.com HTTP/1.1 Content-Type: application/json;charset=utf-8{"title":"test","sub":[1,2,3]}
这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。各大抓包工具如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示 JSON 数据,非常友好。但也有些服务端语言还没有支持这种方式,例如 php 就无法通过 $_POST 对象从上面的请求中获得内容。这时候,需要自己动手处理下:在请求头中 Content-Type 为 application/json 时,从 php://input
里获得原始输入流,再 json_decode
成对象。一些 php 框架已经开始这么做了。
当然 AngularJS 也可以配置为使用 x-www-form-urlencoded 方式提交数据。如有需要,可以参考这篇文章。
我的博客之前提到过 XML-RPC(XML Remote Procedure Call)。它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。典型的 XML-RPC 请求是这样的:
HTMLPOST http://www.example.com HTTP/1.1 Content-Type: text/xml<?xml version="1.0"?><methodCall> <methodName>examples.getStateName</methodName> <params> <param> <value><i4>41</i4></value> </param> </params></methodCall>
XML-RPC 协议简单、功能够用,各种语言的实现都有。它的使用也很广泛,如 WordPress 的 XML-RPC Api,搜索引擎的 ping 服务等等。JavaScript 中,也有现成的库支持以这种方式进行数据交互,能很好的支持已有的 XML-RPC 服务。不过,我个人觉得 XML 结构还是过于臃肿,一般场景用 JSON 会更灵活方便。
이것은 POST를 통해 데이터를 제출하는 가장 일반적인 방법입니다. enctype 속성이 설정되지 않은 경우 브라우저의 기본 ff9c23ada1bcecdd1a0fb5d5a0f18437 양식은 결국 application/x-www-form-urlencoded 모드로 데이터를 제출합니다. 요청은 다음과 유사합니다(이 문서에서는 관련 없는 요청 헤더는 생략됨).
POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded ; charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
먼저 Content-Type은 application/x-www-form-urlencoded로 지정됩니다. 여기서 요구되는 형식은 URL의 쿼리 문자열과 같습니다. 여러 키-값 쌍은 &로 연결되고, 키와 값은 =로 연결되며, ASCII가 아닌 문자만 인코딩하면 됩니다. UrlEncode를 사용합니다. 대부분의 서버측 언어는 이 방법을 잘 지원합니다. 예를 들어, PHP에서는 $_POST['title']이 title의 값을 얻을 수 있고, $_POST['sub']는 하위 배열을 얻을 수 있습니다.
세 번째 요청 본문의 요청 본문은 여러 부분으로 나누어 파일을 업로드할 때 사용됩니다. 이 형식은 이메일 전송에 먼저 사용되어야 하며, 각 필드/파일은 모두 나누어져 있습니다. 경계별로 세그먼트를 구분합니다(Content-Type에 지정). 각 세그먼트는 --와 경계로 시작하고, 설명 헤더 뒤에는 빈 줄이 사용되어 콘텐츠를 연결합니다. 경계에 -- - 표시가 되어 있으며 구조는 아래 그림과 같습니다.
파일로 간주되는지 구별하는 핵심은 파일 유형이 다르기 때문에 Content-Disposition에 파일 이름이 포함되어 있는지 여부입니다. 파일 유형을 나타내는 데에도 사용됩니다. 파일 유형을 모르는 경우 값은 파일이 이진 파일임을 나타내기 위해 application/octet-stream일 수 있습니다. 생략합니다.
양식을 사용하여 파일을 업로드할 때 ff9c23ada1bcecdd1a0fb5d5a0f18437 양식의 enctyped
를 multipart/form-data와 동일하게 만들어야 합니다. 요청 예시를 직접 살펴보겠습니다.
BASHPOST http://www.example.com HTTP/1.1Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA------WebKitFormBoundaryrGKCBY7qhFd3TrwAContent-Disposition: form-data; name="text"title------WebKitFormBoundaryrGKCBY7qhFd3TrwAContent-Disposition: form-data; name="file"; filename="chrome.png"Content-Type: image/pngPNG ... content of chrome.png ...------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary
开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary--
标示结束。关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。
这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。
上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 ff9c23ada1bcecdd1a0fb5d5a0f18437 表单也只支持这两种方式(通过 ff9c23ada1bcecdd1a0fb5d5a0f18437 元素的enctype
属性指定,默认为 application/x-www-form-urlencoded
。其实 enctype
还支持 text/plain
,不过用得非常少)。
随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。
网页中的表单使用POST方法提交时,数据内容的类型是 application/x-www-form-urlencoded,这种类型会:
1.字符"a"-"z","A"-"Z","0"-"9",".","-","*",和"_" 都不会被编码;
2. 공백을 더하기 기호(+)로 변환
3. 텍스트가 아닌 콘텐츠를 "%xy" 형식으로 변환합니다. xy는 두 자리 16진수 값입니다.
4. 각 이름=값 쌍에 그 사이에 앰퍼샌드를 추가하세요.
웹 디자이너가 직면한 많은 문제 중 하나는 다양한 운영 체제 간의 차이점을 처리하는 방법입니다. 이러한 차이로 인해 URL에 문제가 발생합니다. 예를 들어 일부 운영 체제에서는 파일 이름에 공백을 허용하지만 다른 운영 체제에서는 허용하지 않습니다. 대부분의 운영 체제는 파일 이름의 "#" 기호가 특별한 의미를 가지고 있다고 생각하지 않지만, URL에서 "#" 기호는 파일 이름이 끝났음을 나타내고 그 뒤에 조각(부분) 식별자가 있음을 나타냅니다. URL이나 다른 운영 체제에서 특별한 의미를 갖는 기타 특수 문자, 영숫자가 아닌 문자 집합도 비슷한 문제를 야기합니다. 이러한 문제를 해결하기 위해 URL에 사용하는 문자는 다음과 같이 ASCII 문자 집합의 고정 문자 집합 요소여야 합니다:
1. 대문자 A-Z
2. 소문자 a-z
3. 숫자 0- 9
4. 구두점 문자 - _ . ~ * ' (and,)
/ & ? @ # $ + = 및 %도 사용할 수 있지만 각각 고유한 용도가 있습니다 파일인 경우 이름에 이러한 문자( / & ? @ # $ + = % )가 포함되어 있으면 해당 문자와 기타 모든 문자를 인코딩해야 합니다.
인코딩 과정은 매우 간단합니다. ASCII 숫자, 문자 또는 앞서 언급한 구두점이 아닌 모든 문자는 바이트 형식으로 변환됩니다: "%" 뒤에 두 자리 16진수 값이 옵니다. . 공백은 매우 흔하기 때문에 특별한 경우입니다. "%20"으로 인코딩되는 것 외에도 "+"로 인코딩될 수도 있습니다. 더하기 기호(+) 자체는 %2B로 인코딩됩니다. / # = & 및 ?는 URL 부분 사이의 구분 기호가 아닌 이름의 일부로 사용될 때 인코딩되어야 합니다.
경고 이 전략은 문자 집합이 많은 이기종 환경에서는 적합하지 않습니다. 예: 미국 Windows 시스템에서는 é가 %E9로 인코딩됩니다. 미국 Mac에서는 %8E로 인코딩됩니다. 이러한 불확실성의 존재는 기존 URI의 명백한 단점입니다. 따라서 향후 URI 사양은 IRI(International Resource Identifier)를 통해 개선되어야 합니다.
클래스 URL은 자동으로 인코딩이나 디코딩을 수행하지 않습니다. 잘못된 ASCII 및 비ASCII 문자 및/또는 %xx를 포함할 수 있는 URL 개체를 생성할 수 있습니다. 이러한 문자 및 이스케이프 문자는 getPath() 및 toExternalForm() 메소드를 출력 메소드로 사용할 때 자동으로 인코딩되거나 디코딩되지 않습니다. URL 객체를 생성하는 데 사용되는 문자열 객체에 대한 책임은 모든 문자가 적절하게 인코딩되었는지 확인하는 것입니다.
관련 권장 사항:
위 내용은 HTTP 요청 헤더 및 요청 본문에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!