前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从http规范角度来看xmlhttprequest发送请求

从http规范角度来看xmlhttprequest发送请求

作者头像
挥刀北上
发布2019-07-19 15:13:59
1.3K0
发布2019-07-19 15:13:59
举报
文章被收录于专栏:Node.js开发Node.js开发

最近有点怠工,停更好久,今天分享一篇小白文,原生ajax,看标题肯定不同于其他文章的ajax,而是从http规范角度来看xmlhttprequest发送请求。

也就说这篇文章分三个部分,1、http协议,2、xmlhttprequset发送请求,3、两者的结合。

首先咱们来看一下简单的http协议。

浏览器在和服务端进行通讯的时候,发送的所有请求基本都是基于http协议。

http协议最简单的模型是:请求--->处理--->响应。

请求的时候发送的信息被称为请求报文。

请求报文包含以下三个部分:

  1. 请求行(请求报文行)
  2. 请求头(请求报文头)
  3. 请求体(请求报文体)

每次请求必须包含这三部分,一张图演示如下:

这个信息可以在浏览器的network控制栏中可以看到,如图:

上面的图还是有些使人疑惑,哪些信息属于请求行,哪些信息属于请求头,哪些信息属于请求体呢?如图所示:

先说请求行,请求行中包含三个基本信息:

a、请求方法

b、请求的url

c、协议版本。

前两项请求方法和请求的url是可以通过javascript代码可以设置的,而协议版本是由浏览器控制的。

请求头中携带的信息的格式一般都是键值对,大部分是按照http协议规范来设置的,比如Content-Type:application/x-www-form-urlencoded、Content-Type:application/json、Content-Type:multipart/form-data。请求头中的信息一般用来标识此次请求的一些规范信息,比方说上面提到的三个常用请求头,这三个请求头是标识请求体中信息传递的格式。除了标识请求体中的格式还有其他的作用,标识这个请求来自何方的Referer请求头,是否应用缓存的Cache-Control请求头,标识客户端信息的User-Agent请求头...等等。

这里需要注意的是,客户端设置请求头分为两种情况,一种是按照http协议规范严格设置请求头,例如有些请求头客户端不能由用户自己设置,如下:

另外一种情况是自定义设置请求头,设置这种请求头时也需要注意,1、不能和规范名称冲突,2、不同域名下发送ajax请求设置自定义请求头,服务器端必须设置一个特殊的响应头“Access-Control-Allow-Header:*”。

以上便是请求头设置需要注意的内容,下面说一下请求体,当客户端发送get请求时一般不会设置请求体,如果个请求需要传递参数,一般是拼接到url中,也就是在请求行中设置参数。

只有发送post请求时才会设置请求体,设置请求体时需要注意请求体的格式,一般大家使用jquery发送post请求时会自动将数据转换成查询字符串格式,也就是name=zs&age=18,这样格式的数据。并且请求头中会设置Content-Type:application/x-www-form-urlencoded这个请求头。这是模仿表单提交数据的格式。之所以设置请求头,就是要告诉后端服务器,发送的数据格式是这个格式的。

而有些同学在用一些vue框架或者react框架的时候,会使用axios这个库去发送post请求,这个库是默认把数据也就是请求体设置成json格式,并默认加上Content-Type:application/json这个请求头,所以大家在使用的时候要注意区分。这里为什么要着重强调这一点呢? 因为这里需要和服务端人员约定好,你传递数数据的格式,不然服务器端不知道你传递的数据格式就不能正确的将请求体中的信息解析出来。举个简单的例子,请求体中的数据格式是查询字符串,服务器端只支持json格式解析,这就会出现错误。

上面简单说了一下http请求,接下来说下用XMLHttpRequest这个构造函数来发送一个请求,先来看一下发送get请求:

在第三步设置请求头时为了个大家演示setRequestHeader的用法,设置了一个自定义请求头。

这里面需要注意的是:

1、调用open方法设置请求行中的请求方法和请求url,不能设置http版本,前面说过了。版本由浏览器控制。

2、调用setRequestHeader方法设置请求头,这个步骤只能放在open方法之后。

3、设置完请求头和请求行之后就是设置请求体了 ,这里需要注意的是,send方法既可以设置请求体,也是发送请求。get请求不需要设置请求体,post如果传递数据,则将指定格式的数据传入send方法中,为什么是指定数据呢,如果你前面设置请求头设置的是Content-Type:application/x-www-form-urlencoded,那么数据就是查询字符串格式的,如果是Content-Type:application/json那么传入的数据就是json格式的。

最后一步就是设置回调函数,回调函数设置的位置,既可以放在前面也可以放在后面,放在前面所有状态都可以监听到,放在后面有些状态就监听不到了,但这不影响数据的发送,和接收响应数据。

只有在这个回调函数中才能通过得到xhr的response属性值。

下面来看一下post请求的发送:

我设置了请求头,并在send中传递了数据,数据格式与请求头一致,都是查询字符串格式。

看一下network:

如果将请求头改成json格式呢?那么send中的数据格式也要改成json。正确演示如下:

network演示如下:

这里面需要注意的是,使用xmlhttprequest发送post请求如果不设置请求头会是什么样的呢?如图将设置请求头的函数全部注释掉:

查看network:

xmlhttprequest会自动设置Content-Type: text/plain;charset=UTF-8请求头。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nodejs全栈开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档