专栏首页Node.js开发从http规范角度来看xmlhttprequest发送请求

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

最近有点怠工,停更好久,今天分享一篇小白文,原生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请求头。

本文分享自微信公众号 - nodejs全栈开发(geekclass),作者:挥刀北上

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-09-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 揭秘简单请求与复杂请求

    开发网站时经常会用到跨域资源共享(简称cors,后面使用简称)来解决跨域问题,但是在使用cors的时候,http请求会被划分为两类,简单请求和复杂请求,而这两种...

    挥刀北上
  • host、referer和origin的区别

    举个简单的例子: 我在IP地址为127.0.0.1的服务器上,通过apache配置了两个虚拟主机:a.com,b.com,这两个域名通过DNS解析都会指向127...

    挥刀北上
  • axios使用指南

    axios作为jquery中ajax的替代产物,越来越多的被前端工程师所使用,这个npm包的使用非常灵活和强大,并且在nodejs端和浏览器端通用,在浏览器端a...

    挥刀北上
  • axios发送两次请求及遇到的坑

    在以前的Vue项目商城中,使用axios组件做数据请求,在页面交互中发现会发送两次网络请求,因为没有造成什么影响,一直也没有追究原因。在一个新的项目中,需要加入...

    honey缘木鱼
  • 每天一道面试题 | day07

    GET请求获取Request-URI所标识的资源,例如:在浏览器的地址栏中输入网址的方式访问网页时,浏览器采用GET方法向服务器获取资源。

    剑走天涯
  • 面试官:说说你对 options 请求的理解

    简单来说,就是可以用 options 请求去嗅探某个请求在对应的服务器中都支持哪种请求方法。

    Tusi
  • 测试工具Fiddler(三)—— 常见功能介绍

    3、autoresponder: 文件代理:可以使用fiddler来自定义请求返回的文件。

    小菠萝测试笔记
  • Provisional headers are shown in Chrome network tab

    细心的同学应该留意到,新版开发者工具的 Network 面板中,某些请求头后面会跟着下面这行文字:

    Jerry Wang
  • 干货 | 计算密集型服务的负载均衡策略

    罗茂林,携程国际机票后台研发总监,主要负责国际机票引擎的研发工作。致力于系统性能优化和研发效率提升。

    携程技术
  • 小结HTTP状态码

    作为一个web开发工程师,我们平时都会和诸如200, 304, 404, 501等状态码打交道,那么它们是什么意思呢?今天,我们来聊聊~

    嘉明

扫码关注云+社区

领取腾讯云代金券