服务器无法在发送 http 标头之后设置内容类型。_HTTP概述及其工作方式

c5697ae7a6d19f577721931aac83fd98.png
HTTP是允许提取资源(例如HTML文档)的协议。它是Web上任何数据交换的基础,并且是客户端-服务器协议,这意味着请求是由收件人(通常是Web浏览器)发起的。从获取的不同子文档中重建完整的文档,例如文本,布局描述,图像,视频,脚本等

b384e5a9fce3b5862d4e6d7a0660a54a.png

客户端和服务器通过交换单个消息进行通信(例如 相对于数据流)。客户端(通常是Web浏览器)发送的消息称为请求,而服务器作为答案发送的消息称为响应。

0da847d1acb1a22db3a7742e3296c661.png

HTTP是在1990年代初期设计的,是随时间发展的可扩展协议。它是通过TCP或TLS加密的TCP连接发送的应用层协议,尽管理论上可以使用任何可靠的传输协议。由于其可扩展性,它不仅可用于获取超文本文档,而且还可用于获取图像和视频,或将内容发布到服务器(如HTML表单结果)。 HTTP还可以用于获取部分文档以按需更新Web页面。

基于HTTP的系统的组件

HTTP是一种客户端-服务器协议:请求由一个实体,用户代理(或代表它的代理)发送。大多数情况下,用户代理是Web浏览器,但也可以是任何东西,例如,可以爬网以填充并维护搜索引擎索引的机器人。

每个单独的请求都发送到服务器,由它处理并提供一个答案,称为响应。在客户端和服务器之间有许多实体(统称为代理),它们执行不同的操作并充当网关或缓存.

65e8c57c1866f14853993f180f176dbc.png

实际上,浏览器和服务器之间有更多处理请求的计算机:路由器,调制解调器等。由于Web的分层设计,这些隐藏在网络和传输层中。

HTTP在应用程序层之上。尽管对于诊断网络问题很重要,但是底层几乎与HTTP的描述无关。

客户:用户代理

所述用户代理是作用于用户的代表任何工具。该角色主要由Web浏览器执行。其他可能性是工程师和Web开发人员用来调试其应用程序的程序。

浏览器始终是发起请求的实体。它绝不是服务器(尽管多年来已经添加了一些机制来模拟服务器启动的消息)。

要显示网页,浏览器会发送原始请求以获取代表该页面的HTML文档。然后,它将解析该文件,并发出与执行脚本,要显示的布局信息(CSS)以及页面中包含的子资源(通常为图像和视频)相对应的其他请求。

然后,Web浏览器将这些资源混合在一起,以向用户提供完整的文档,即Web页面。浏览器执行的脚本可以在以后的阶段中获取更多资源,浏览器会相应地更新网页。

网页是超文本文档。这意味着显示的文本的某些部分是可以激活(通常通过单击鼠标)以获取新网页的链接,从而允许用户定向其用户代理并浏览Web。浏览器将这些指示转换为HTTP请求,并进一步解释HTTP响应以向用户提供清晰的响应。

Web服务器

在通信通道的另一侧是服务器,该服务器根据客户端的请求提供文档。一台服务器实际上实际上只是一台机器:这是因为它实际上可能是服务器的集合,共享负载(负载平衡)或询问其他计算机(例如缓存,数据库服务器或电子商务)的复杂软件服务器),按需全部或部分生成文档。

服务器不一定是一台计算机,但是可以在同一台计算机上托管多个服务器软件实例。使用HTTP / 1.1和Host标头,它们甚至可以共享相同的IP地址。

代理

在Web浏览器和服务器之间,许多计算机和机器中继HTTP消息。由于Web堆栈的分层结构,因此其中大多数都在传输,网络或物理级别上运行,在HTTP层上变得透明,并可能对性能产生重大影响。在应用程序层上运行的那些通常称为代理

它们可以是透明的,可以转发接收到的请求而不进行任何更改,也可以是非透明的,在这种情况下,它们将以某种方式更改请求,然后再将其传递给服务器。代理可以执行许多功能:

  • 缓存(缓存可以是公共缓存,也可以是私有缓存,例如浏览器缓存)
  • 过滤(例如防病毒扫描或家长控制)
  • 负载平衡(以允许多个服务器满足不同的请求)
  • 身份验证(控制对不同资源的访问)
  • 日志记录(允许存储历史信息

HTTP的基本方面

HTT协议很简单

HTTP通常被设计为简单易读,即使HTTP / 2通过将HTTP消息封装到帧中而增加了复杂性。人们可以阅读和理解HTTP消息,从而为开发人员提供了更轻松的测试,并为新手提供了降低的复杂性。

HTTP是可扩展

的HTTP / 1.0引入了HTTP 标头使该协议易于扩展和试验。甚至可以通过客户端与服务器之间关于新标头语义的简单协议来引入新功能

HTTP是无状态的,但不是无会话的

HTTP是无状态的:在同一连接上连续执行的两个请求之间没有链接。对于试图例如使用电子商务购物篮连贯地与某些页面进行交互的用户而言,这立即具有问题。

但是,尽管HTTP本身的核心是无状态的,但HTTP cookie允许使用有状态会话。使用标头可扩展性,HTTP Cookie被添加到工作流中,从而允许在每个HTTP请求上创建会话以共享相同的上下文或相同的状态。

HTTP和连接

连接是在传输层控制的,因此从根本上来说不在HTTP的范围之内。尽管HTTP不需要底层的传输协议是基于连接的;只要求它是可靠的,或不会丢失消息(因此在最小呈现错误)。

在Internet上两种最常见的传输协议中,TCP是可靠的,而UDP不是。因此,HTTP依赖于基于连接的TCP标准。

在客户端和服务器可以交换HTTP请求/响应对之前,它们必须建立TCP连接,此过程需要多次往返。HTTP / 1.0的默认行为是为每个HTTP请求/响应对打开一个单独的TCP连接。当多个请求被连续发送时,这比共享单个TCP连接的效率低.

为了缓解此缺陷,HTTP / 1.1引入了流水线技术(事实证明难以实现)和持久连接:可以使用Connection标头。HTTP / 2通过在单个连接上多路复用消息来进一步推进,从而使连接保持温暖和更高效。

实验正在进行中,以设计更适合HTTP的更好的传输协议。例如,谷歌正在试验基于UDP的QUIC,以提供更可靠和有效的传输协议。

HTTP可以控制什么

随着时间的流逝,HTTP的这种可扩展性质允许对Web进行更多控制和功能。缓存或身份验证方法是HTTP历史记录中早期处理的函数。相比之下,放宽原点约束的功能仅在2010年代才添加。

可以通过HTTP控制的常见功能列表.

  • 缓存中。可以通过HTTP控制如何缓存文档。服务器可以 指示代理和客户端有关要缓存的内容以及缓存的时间。客户端可以指示中间缓存代理忽略存储的文档。
  • 放宽原点约束。为了防止监听和其他隐私入侵,Web浏览器在网站之间强制严格隔离。只有具有相同来源的页面才能访问网页的所有信息。尽管这样的约束是服务器的负担,但是HTTP标头可以放松服务器端的这种严格分隔,使文档成为来自不同域的信息的拼凑而成。甚至可能有与安全相关的原因。
  • 身份验证。某些页面可能受到保护,因此只有特定用户才能访问它们。HTTP可以使用以下方式通过HTTP提供基本身份验证:WWW-Authenticate和类似的标头,或者通过使用HTTP cookie设置特定的会话。
  • 代理和隧道。服务器或客户端通常位于Intranet上,并向其他计算机隐藏其真实IP地址。然后,HTTP请求将通过代理来穿越此网络障碍。并非所有代理都是HTTP代理。SOCKS协议例如在较低级别上运行。这些代理可以处理其他协议,例如ftp。
  • 会议。使用HTTP cookie可让您将请求与服务器状态链接起来。尽管基本HTTP是无状态协议,但这仍会创建会话。这不仅对电子商务购物篮有用,而且对任何允许用户配置输出的站点都有用。

HTTP流

  1. 打开一个TCP连接:TCP连接用于发送一个或多个请求,并接收答案。客户端可以打开一个新的连接,重用现有的连接,或打开到服务器的多个TCP连接。
  2. 发送一条HTTP消息:HTTP消息(在HTTP / 2之前)是人类可读的。使用HTTP / 2,这些简单的消息被封装在框架中,使其无法直接读取,但是原理保持不变。例如:

8054111393b541fef7ba659af9208204.png

3. 读取服务器发送的响应,例如:

b601e37f47d9bb6a1e4e975808c625de.png

4. 关闭该连接或将其重新用于其他请求。

如果激活了HTTP流水线,则可以发送多个请求,而无需等待完全接收到第一个响应。事实证明,HTTP管道难以在现有网络中实现,现有网络中的旧软件与现代版本共存。HTTP管道已被HTTP / 2取代,并在一个帧内具有更强大的复用请求。

HTTP消息

HTTP消息(在HTTP / 1.1及更早版本中定义)是人类可读的。在HTTP / 2中,这些消息被嵌入到二进制结构(框架)中,从而可以进行优化,例如压缩标头和多路复用。即使在此版本的HTTP中仅发送原始HTTP消息的一部分,每个消息的语义也不会改变,并且客户端会(虚拟地)重构原始HTTP / 1.1请求。因此,理解HTTP / 1.1格式的HTTP / 2消息很有用。

HTTP消息有两种类型,即请求和响应,每种都有自己的格式。

请求

  • 示例HTTP请求

d4cc05df3f69a069ceb95f4097c47d4a.png

请求包含以下元素:

  • HTTP 方法,通常是动词,例如href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET?ref=hackernoon.com">GET, ref="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST?ref=hackernoon.com">POST 或类似的名词 ="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS?ref=hackernoon.com">OPTIONS 要么 ref="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD?ref=hackernoon.com">HEAD定义客户端要执行的操作。通常,客户端希望获取资源(使用GET)或发布HTML表单的值(使用Post),但在其他情况下可能需要执行更多操作。
  • 要获取的资源的路径;从上下文中显而易见的元素中剥离资源的URL,例如, 没有协议(http://)或者是TCP端口(此处为80端口);
  • HTTP协议版本
  • 传送服务器附加信息的可选头.
  • 对于诸如POST之类的某些方法,类似于响应中包含发送资源的方法,则为一个主体

响应

b0cd2888c7ca372b346ca21ea5c759cc.png
  • 响应包含以下元素
    • 遵循的http协议版本.
    • 返回的状态码, 表示如果请求成功,或者没有请求成功的状态反馈.
    • 状态消息, 状态代码 非权威必简短描述.HTTP标头, 例如用于请求的标头.
    • (可选)包含获取的资源主体.

基于HTTP的API

基于HTTP的最常用API是 XMLHttpRequest API,可用于在 user agent和一台服务器。现代Fetch API 通过更强大,更灵活的功能集提供相同的功能。

另一个API,即服务器发送的事件,是一种单向服务,它允许服务器使用HTTP作为传输机制将事件发送到客户端。使用EventSource客户端打开一个接口并建立事件处理程序。客户端浏览器会自动将到达HTTP流的消息转换为适当的ef="https://developer.mozilla.org/en-US/docs/Web/API/Event?ref=hackernoon.com">Event 对象,将它们传递给已为事件注册的事件处理程序 ref="https://developer.mozilla.org/en-US/docs/Web/API/Event/type?ref=hackernoon.com">type 如果知道的话 onmessage 事件处理程序(如果未建立特定于类型的事件处理程序)。

结论

HTTP是易于使用的可扩展协议。客户端-服务器结构与简单添加标头的功能相结合,使HTTP可以随着Web的扩展功能一起前进。

尽管HTTP / 2增加了一些复杂性,但通过将HTTP消息嵌入帧中以提高性能,消息的基本结构自HTTP / 1.0起一直保持不变。会话流保持简单,可以对其进行调查,并使用简单的HTTP消息监视器进行调试。

「译」: 原文链接
https://hackernoon.com/an-overview-of-http-and-how-it-works-y11c3y5a​hackernoon.com
### 回答1: 跨域访问是指在浏览器中,通过JavaScript代码从一个域名的网页去请求另一个域名的资源时,会被同源策略所限制而无法正常访问。为了解决这个问题,我们需要通过设置HTTP响应标头来允许跨域访问。 在HTTP响应中,我们可以设置一些特殊的标头,如"Access-Control-Allow-Origin"、"Access-Control-Allow-Methods"、"Access-Control-Allow-Headers"等来控制在跨域请求时的行为。 "Access-Control-Allow-Origin"标头用于指定允许访问该资源的域,可以设置为具体的域名或通配符"*",表示允许任何域进行访问。 "Access-Control-Allow-Methods"标头用于指定允许的请求方法,如GET、POST、PUT等。 "Access-Control-Allow-Headers"标头用于指定允许的请求头,如Content-Type、Authorization等。 除了以上标头,还可以使用其他一些标头来进一步控制跨域请求。此外,在前端代码中,还需要使用XMLHttpRequest对象或Fetch API发送请求时,设置"withCredentials"为true,并在后端服务器中作出相应的处理,允许发送带有身份凭证的跨域请求。 需要注意的是,在设置跨域访问的时候,应该明确指定允许访问的域名,避免未经授权的域名访问可能引发的安全问题。 通过设置HTTP响应标头,我们可以解决跨域访问的问题,实现不同域名之间的数据交互与资源共享。 ### 回答2: 跨域访问是指在Web开发中,浏览器执行JavaScript代码请求不同源的资源时,由于浏览器的同源策略限制,会导致请求失败。为了实现跨域访问,我们需要在服务器设置HTTP响应标头。 常见的跨域访问解决方案是使用CORS(跨域资源共享)。在服务器设置CORS标头,允许特定的源发起跨域请求。通过设置标头中的"Access-Control-Allow-Origin"字段,可以指定允许请求的源。例如,设置为"*"表示允许任何源发起请求。 另一个常见的解决方案是使用JSONP(JSON with Padding)。JSONP利用了script标签不受同源策略限制的特性。通过在服务器端返回一个回调函数的调用,将数据作为参数传递给回调函数,实现跨域数据的获取。 除了CORS和JSONP,还可以使用代理服务器来解决跨域访问问题。在客户端发送请求时,将请求发送至代理服务器,然后代理服务器再将请求转发至目标服务器,并将响应返回给客户端。这种方式绕过了浏览器的同源策略限制。 在设置HTTP响应标头的时候,需要注意安全性的考虑。过于宽松的设置可能导致跨域攻击。因此,我们应该根据需求明确允许的来源,并考虑设置其他相关的CORS标头字段,比如"Access-Control-Allow-Methods"和"Access-Control-Allow-Headers"等。 总之,跨域访问需要通过在服务器设置HTTP响应标头来解决限制问题。CORS、JSONP和代理服务器是常见的实现跨域访问的解决方案。合理设置标头字段可以确保安全性和功能的平衡。 ### 回答3: 跨域访问是指在Web开发中,浏览器中运行的一个网页,向另一个域名下的资源发起请求,但是由于浏览器的同源策略限制,跨域请求是被禁止的。为了解决这个问题,需要在服务器http响应标头中进行设置。 首先,服务器需要在响应中设置Access-Control-Allow-Origin标头,该标头指定了被允许进行跨域访问的原始域名。可以设置为"*"表示允许来自所有域名的访问,也可以设定为特定的域名,例如"www.example.com"。 其次,服务器还可以设置其他的Access-Control-Allow-*标头,来进一步控制跨域请求的细节。例如,Access-Control-Allow-Methods标头可以指定允许的HTTP方法,Access-Control-Allow-Headers标头可以指定允许的HTTP头,Access-Control-Max-Age标头可以设定预检请求的有效期等。 此外,如果在跨域请求中使用了携带身份凭证的cookie,还需要设置Access-Control-Allow-Credentials标头为true,以允许携带凭证。 综上所述,跨域访问需要在服务器http响应标头设置相关的Access-Control-*标头,以允许来自其他域名的请求访问服务器的资源。通过设置合适的标头,就可以在一定程度上解决跨域访问的限制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值