晴明的博客园 GitHub      CodePen      CodeWars     

[http] URI

HTTP

超文本传输协议 (HTTP) 是一种用于传输超媒体文档的应用层协议。
HTTP 协议也是一个无状态协议,这就意味着服务并不能保留两个请求之间的数据(状态)。尽管 HTTP 协议通常是基于 TCP/IP 的,但它实际上可以在任何可靠的传输层协议上使用,所谓可靠的协议就是指那些不会隐式丢弃消息的协议,比如 UDP。

HTTP 请求的内容通称为"资源"。”资源“这一概念非常宽泛,它可以是一份文档,一张图片,或所有其他你能够想到的格式。每个资源都由一个 (URI) 来进行标识。

一般情况下,资源的名称和位置由同一个 URL(统一资源定位符,它是 URI 的一种)来标识。

URLs

URI 的最常见形式是统一资源定位符 (URL),它也被称为 Web 地址。
在浏览器的地址栏中输入任一网站地址,浏览器就会加载相应的网页(资源)。
URL 由多个必须或可选的组件构成。

URNs

URN 是另一种形式的 URI,它通过特定命名空间中的唯一名称来标识资源。

统一资源标识符的语法 (URI)

protocol(协议)

http:// 告诉浏览器使用何种协议。对于大部分 Web 资源,通常使用 HTTP 协议或其安全版本,HTTPS 协议。另外,浏览器也知道如何处理其他协议。

方案 | 描述

  • | -
    data | Data URIs
    file | 指定主机上文件的名称
    ftp | 文件传输协议
    http/https | 超文本传输​​协议/安全的超文本传输协议
    mailto | 电子邮件地址
    ssh | 安全 shell
    tel | 电话
    urn | 统一资源名称
    view-source | 资源的源代码
    ws/wss (加密的) | WebSocket 连接

domain(主机)

www.example.com 既是一个域名,也代表管理该域名的机构。它指示了需要向网络上的哪一台主机发起请求。当然,也可以直接向主机的 IP address 地址发起请求。但直接使用 IP 地址的场景并不常见。

port(端口)

:80 是端口。它表示用于访问 Web 服务器上资源的技术“门”。如果访问的该 Web 服务器使用HTTP协议的标准端口(HTTP为80,HTTPS为443)授予对其资源的访问权限,则通常省略此部分。否则端口就是 URI 必须的部分。

path(路径)

/path/to/myfile.html 是 Web 服务器上资源的路径。在 Web 的早期,类似这样的路径表示 Web 服务器上的物理文件位置。现在,它主要是由没有任何物理实体的 Web 服务器抽象处理而成的。

parameters(参数)

?key1=value1&key2=value2 是提供给 Web 服务器的额外参数。这些参数是用 & 符号分隔的键/值对列表。Web 服务器可以在将资源返回给用户之前使用这些参数来执行额外的操作。每个 Web 服务器都有自己的参数规则。

anchor(锚点)

#SomewhereInTheDocument 是资源本身的某一部分的一个锚点。锚点代表资源内的一种“书签”,它给予浏览器显示位于该“加书签”点的内容的指示。
例如,在HTML文档上,浏览器将滚动到定义锚点的那个点上;
在视频或音频文档上,浏览器将转到锚点代表的那个时间。
值得注意的是 # 号后面的部分,也称为片段标识符,永远不会与请求一起发送到服务器。

Data URLs

Data URLs,即前缀为 data:scheme 的URL,其允许内容创建者向文档中嵌入小文件。

语法

Data URLs 由四个部分组成:
前缀(数据:),指示数据类型的MIME类型,如果非文本则为可选的base64令牌,数据本身:

data:[<mediatype>][;base64],<data>

mediatype 是个 MIME 类型的字符串,例如 image/jpeg 表示 JPEG 图像文件。如果被省略,则默认值为 text/plain;charset=US-ASCII

如果数据是文本类型,可以直接将文本嵌入 (根据文档类型,使用合适的实体字符或转义字符)。如果是二进制数据,可以将数据进行base64编码之后再进行嵌入。

一些示例:

# 简单的 text/plain 类型数据
data:,Hello%2C%20World!
    
# base64 编码过的数据
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
    
# 一个HTML文档源代码 <h1>Hello, World</h1>
data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E

# 一个会执行 JavaScript alert 的 HTML 文档。注意,script 闭标签是必须的。
data:text/html,<script>alert('hi');</script>  

给数据作 base64 编码

在Linux中可以使用 uuencode 命令行工具来简单实现编码:

uuencode -m infile remotename

infile 参数表示要作 base64编码的文件名称,remotename is the remote name for the file, which isn't actually used in data URLs.

输出结果如下:

begin-base64 664 test
YSBzbGlnaHRseSBsb25nZXIgdGVzdCBmb3IgdGV2ZXIK
====

在网页上使用 JavaScript
atob() 解码一个已经被base-64编码过的数据。
btoa() 将ascii字符串或二进制数据转换成一个base64编码过的字符串,该方法不能直接作用于Unicode字符串。

常见问题

1.语法
data URLs 的格式很简单,但很容易会忘记把逗号加在 "data" 协议名后面,在对数据进行 base64 编码时也很容易发生错误。

2.HTML代码格式化
一个 data URL 是一个文件中的文件,相对于文档来说这个文件可能就非常的长。因为 data URL 也是 URL,所以 data 会用空白符(换行符, 制表符, 空格)来对它进行格式化。但如果数据是经过 base64 编码的,就可能会遇到一些问题。

3.长度限制
虽然浏览器支持无限长度的 data URLs,但是标准中并没有规定浏览器必须支持任意长度的 data URIs。
比如,Opera 11浏览器限制 URLs 最长为 65535 个字符,这意外着 data URLs 最长为 65529 个字符(如果使用纯文本 data:, 而不是指定一个 MIME 类型的话,那么 65529 字符长度是编码后的长度,而不是源文件)。

4.缺乏错误处理
MIME类型错误或者base64编码错误,都会造成data URIs无法被正常解析, 但不会有任何相关错误提示.

5.不支持查询字符串
一个data URI的数据字段是没有结束标记的,所以尝试在一个data URI后面添加查询字符串会导致,查询字符串也一并被当作数据字段.例如:

    data:text/html,lots of text...<p><a name%3D"bottom">bottom</a>?arg=val

这个 data URL 代表的 HTML 源文件内容为:

lots of text...<p><a name="bottom">bottom</a>?arg=val

MIME类型

MIME类型是一种通知客户端其接收文件的多样性的机制:文件后缀名在网页上并没有明确的意义。因此,使服务器设置正确的传输类型非常重要,所以正确的MIME类型与每个文件一同传输给服务器。在网络资源进行连接时,浏览器经常使用MIME类型来决定执行何种默认行为。

因为有很多种文件的存在,所以也有很多种MIME类型。
所有的MIME类型

为了传递文件类型信息,MIME类型并不是唯一的选择:

在微软Windows系统中,文件命后缀经常会被使用。但并不是所有操作系统认为这些后缀是有意义的(尤其是Linux和Mac OS),它们更偏好于外部MIME类型,但是也不能保证它们就是对的。
Magic numbers. 在一些文件的语法中,允许使用其构造类型来区分。比如说GIF文件以16进制值47 49 46 38开始 [GIF89] ,而PNG文件是以89 50 4E 47 [.PNG] 。并不是所有类型的文件都会有magic numbers,所以这也不是一个100%可靠的方式。

正因如此,在web中MIME类型的正确设置非常重要。浏览器和服务器尝试使用后缀名或magic number去定义MIME类型,以用来检测其对应的一致性,以及尝试对一个通用的类型寻找正确的MIME类型。

语法

通用结构

type/subtype

MIME的组成结构非常简单;由类型与子类型两个字符串中间用/分隔而组成。并不允许空格存在。
type 表示可以被分为复数子类的独立类型。
subtype 表示细分后的每个类型。

MIME类型对大小写不敏感,但是传统写法都是小写。

Discrete types

类型 描述 典型示例
text 表明文件是普通文本,理论上是可读的语言 text/plain, text/html, text/css, text/javascript
image 表明是某种图像。不包括视频,但是动态图(比如动态gif)也使用image类型 image/gif, image/png, image/jpeg, image/bmp, image/webp
audio 表明是某种音频文件 audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav
video 表明是某种视频文件 video/webm, video/ogg
application 表明是某种二进制数据 application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf

对于text文件类型若没有特定的subtype,就使用 text/plain。
类似的,二进制文件没有特定或已知的 subtype,即使用 application/octet-stream。

Multipart types

multipart/form-data
multipart/byteranges

Multipart types 表示细分领域的文件类型的种类,经常对应不同的 MIME类型。这是 复合文 件的一种表现方式。对于 multipart/form-data 的例外部分,可以使用HTML Forms 和 POST 方法来解决,以及使用状态码206 Partial Content 来发送整个文件的子集,而HTTP不能处理的复合文件使用一个特殊的方式:将信息直接传送给浏览器(这时可能会建立一个“另存为”窗口,但是却不知道如何去显示内联文件。)

重要的MIME类型

application/octet-stream

这是应用程序文件的默认值。意思是未知的应用程序文件 ,浏览器一般不会自动执行或询问执行。浏览器会像对待设置了 HTTP头Content-Disposition 值为“附件”的文件一样来对待这类文件。

text/plain

文本文件默认值。意思是 未知的文本文件 ,浏览器认为是可以直接展示的。

text/plain 并不是意味着 某种文本数据 。如果浏览器想要一个文本文件的明确类型,浏览器并不会考虑他们是否匹配。比如说,如果通过一个表明是下载CSS文件的链接下载了一个 text/plain 文件。如果提供的信息是text/plain,浏览器并不会认出这是有效的CSS文件。CSS类型需要使用text/css。

text/css

任何一个CSS文件想要在网页上被解释执行就必须为text/css文件。但是服务器经常不会分辨出使用.css后缀的CSS文件,并且将其MIME类型设置为text/plainapplication/octet-stream 发送。
在这种情况下,文件并不能被浏览器识别为CSS文件并且会被直接忽略。所以特别注意要给CSS文件设置正确的类型。

text/html

HTML 文件的类型.另一个用于XHTML的MIME类型是 application/xml+html. 但是现在很少用了(HTML5统一了这个格式)。

图片类型

图片类型是在网页中使用的,唯一被广泛识别以及考虑过web安全的类型:

MIME | 类型 | 图片类型
-|-
image/gif | GIF 图片 (无损耗压缩方面被PNG所替代)
image/jpeg | JPEG 图片
image/png | PNG 图片
image/svg+xml | SVG图片 (矢量图)

音频与视频类型

HTML并没有明确定义被用于<audio><video>元素所支持的文件类型。

在web环境最常用的视频文件的格式:

MIME 类型 音频或视频类型
audio/wave 、audio/wav 、audio/x-wav 、audio/x-pn-wav 音频流媒体文件。一般支持PCM音频编码,其他解码器有限支持(如果有的话)。
audio/webm WebM 音频文件格式。Vorbis 和 Opus 是其最常用的解码器。
video/webm 采用WebM视频文件格式的音视频文件。VP8 和 VP9是其最常用的视频解码器。Vorbis 和 Opus 是其最常用的音频解码器。
audio/ogg 采用OGG多媒体文件格式的音频文件。 Vorbis 是这个多媒体文件格式最常用的音频解码器。
video/ogg 采用OGG多媒体文件格式的音视频文件。常用的视频解码器是 Theora;音频解码器为Vorbis 。
application/ogg 采用OGG多媒体文件格式的音视频文件。常用的视频解码器是 Theora;音频解码器为Vorbis 。

multipart/form-data

multipart/form-data可用于HTML表单从浏览器发送信息给服务器。 作为多部分文档格式,它由边界线(一个由'--'开始的字符串)划分出的不同部分组成。每一部分有自己的实体,以及自己的 HTTP 请求头,Content-Disposition和 Content-Type 用于文件上传领域,最常用的 (Content-Length 因为边界线作为分隔符而被忽略)。

Content-Type: multipart/form-data; boundary=aBoundaryString
(other headers associated with the multipart document as a whole)

--aBoundaryString
Content-Disposition: form-data; name="myFile"; filename="img.jpg"
Content-Type: image/jpeg

(data)
--aBoundaryString
Content-Disposition: form-data; name="myField"

(data)
--aBoundaryString
(more subparts)
--aBoundaryString--

multipart/byteranges

multipart/byteranges 用于把部分的响应报文发送回浏览器。当发送状态码 206 Partial Content 时,这个MIME类型用于指出这个文件由若干部分组成,每一个都有其请求范围。就像其他很多类型Content-Type使用分隔符来制定分界线。每一个不同的部分都有Content-Type这样的HTTP头来说明文件的实际类型,以及 Content-Range来说明其范围。

HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
Content-Length: 385

--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 100-200/1270

eta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="vieport" content
--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 300-400/1270

-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: "Open Sans", "Helvetica
--3d6b6a416f9b5--

设置正确的MIME类型的重要性

很多web服务器使用默认的 application/octet-stream 来发送未知类型。出于一些安全原因,对于这些资源浏览器不允许设置一些自定义默认操作,导致用户必须存储到本地以使用。常见的导致服务器配置错误的文件类型如下所示:

RAR编码文件。
在这种情况,理想状态是,设置真实的编码文件类型;但这通常不可能(可能是服务器所未知的类型或者这个文件包含许多其他的不同的文件类型)。这这种情况服务器将发送 application/x-rar-compressed 作为MIME类型,用户不会将其定义为有用的默认操作。

音频或视频文件。
只有正确设置了MIME类型的文件才能被

专有文件类型。
是专有文件时需要特别注意。使用 application/octet-stream 作为特殊处理是不被允许的:对于一般的MIME类型浏览器不允许定义默认行为(比如“在Word中打开”)

MIME 嗅探

在缺失 MIME 类型或客户端认为文件设置了错误的 MIME 类型时,浏览器可能会通过查看资源来进行MIME嗅探。每一个浏览器在不同的情况下会执行不同的操作。因为这个操作会有一些安全问题,有的 MIME 类型表示可执行内容而有些是不可执行内容。浏览器可以通过请求头 Content-Type 来设置 X-Content-Type-Options 以阻止MIME嗅探。

域名

在一个 HTTP 网址中,在初始 http://https:// 后的第一个子字符串称为域。它是文档所在的服务器的名称。

一个服务器不一定是一个独立的物理机:几台服务器可以驻留在同一台物理机器上,或者一台服务器可以通过几台机器进行处理,协作处理并响应或负载均衡它们之间的请求。关键点在于语义上一个域名代表一个单独的服务器。

规范网址方式

使用 HTTP 301 重定向

将尝试使访问非规范网址的浏览器重定向到其规范的等效网址。

    服务器收到 http://www.example.org 请求(当规范域名是 example.org 时)
    服务器则以代码 301 与头 Location :http://example.org
    该客户端发出的规范的域名请求被重定向到:http://example.org

可以将一个特殊的 HTML 元素添加到网页指示什么网页的标准地址,这对页面的访问者没有影响,但在搜索引擎检索时会告诉搜索引擎当页面实际的地址。通过这种方式,搜索引擎不需要索引同一页面多次,那样可能导致它被视为重复的内容或垃圾邮件,甚至从搜索引擎结果中删除或者降低你的页面显示排名。

当加入这样一个标签,会告诉搜索引擎,提供的相同内容的两个域名那一个是规范的。
以前面的例子为例,http://www.example.org 将提供与 http://example.org 相同的内容,但有一个附加的 头部元素:

<link href="http://example.org/whaddup" rel="canonical">

不同于以往,浏览器历史记录将考虑非 www 的网址作为独立的条目。

posted @ 2017-08-15 19:10  晴明桑  阅读(657)  评论(0编辑  收藏  举报