资讯专栏INFORMATION COLUMN

前后端联调之Form Data与Request Payload,你真的了解吗?

Fundebug / 3016人阅读

摘要:前言做过前后端联调的小伙伴,可能有时会遇到一些问题。它是请求中空行的后面那部分。这就是它向你展示的。值得形式是以的形式提交的。传递对象的时候,默认为类型的值,与非时,的区别。如果是字符串的话,后端解析的内容时候,肯定要去解析啦。

前言

做过前后端联调的小伙伴,可能有时会遇到一些问题。例如,我明明传递数据给后端了,后端为什么说没收到呢?这时候可能就会就会有小伙伴陷入迷茫,本文从chrome-dev-tools(F12调试器)中看到的FormDataRequestBody,给小伙伴们提供一种可能的思路。也给小伙伴们提供一些问题的探究方法。

简介

什么是FormData?什么是RequestPayload?不解释,直接上图:

区别?

因为这里触及了我的知识盲区,所以有了本文。这个答案是我在stackoverflow上得到的。首先还是贴问题,贴答案。

What"s the difference between “Request Payload” vs “Form Data” as seen in Chrome dev tools Network tab。
中文翻译:chrome开发者工具中的Request Payload与Form Data有什么区别?

高票回答:

The Request Payload - or to be more precise: payload body of a HTTP Request - is the data normally send by a POST or PUT Request. It"s the part after the headers and the CRLF of a HTTP Request.

A request with Content-Type: application/json may look like this:

POST /some-path HTTP/1.1
Content-Type: application/json

{ "foo" : "bar", "name" : "John" }

If you submit this per AJAX the browser simply shows you what it is submitting as payload body. That’s all it can do because it has no idea where the data is coming from.

If you submit a HTML-Form with method="POST" and Content-Type: application/x-www-form-urlencoded or Content-Type: multipart/form-data your request may look like this:

POST /some-path HTTP/1.1
Content-Type: application/x-www-form-urlencoded

foo=bar&name=John

In this case the form-data is the request payload. Here the Browser knows more: it knows that bar is the value of the input-field foo of the submitted form. And that’s what it is showing to you.

So, they differ in the Content-Type but not in the way data is submitted. In both cases the data is in the message-body. And Chrome distinguishes how the data is presented to you in the Developer Tools.

翻译过来是说:
Request Payload更准确的说是http request的payload body。一般用在数据通过POST请求或者PUT请求。它是HTTP请求中空行的后面那部分。(PS:这里涉及一个http常被问到的问题,http请求由哪几部分组成,一般是请求行,请求头,空行,请求体。payload body应该是对应请求体。)

一个请求伴随着header设置为Content-Type: application/json时候,看起来可能像这样:

POST /some-path HTTP/1.1
Content-Type: application/json

{ "foo" : "bar", "name" : "John" }

如果你正常请求一个ajax。浏览器会简单的将你提交的内容作为payload展示出来,这就是它所能做的,因为它不知道数据来自哪里。

如果你提交了一个html表单并且配置上了method="post",并且设置了Content-Type: application/x-www-form-urlencoded或者Content-Type: multipart/form-data。那么你的请求可能长这个样:

POST /some-path HTTP/1.1
Content-Type: application/x-www-form-urlencoded

foo=bar&name=John

这里的form-data就是request payload。在这里,浏览器知道更多:它知道bar是提交表单的输入字段foo的值。这就是它向你展示的。

所以区别就是,他们只是因为Content-Type设置的不同,并不是数据提交方式的不同,这两种提交都会将数据放在message-body中。但是chrome浏览器的开发者工具会根据这个ContentType区分显示方式。

细节

好了,到这里我们知道了,其实都是放到了payload中。那么具体有什么区别呢?为什么有时候后端拿不到值呢?这就不得不说对payload的解析方式了。我们以几个chrome下的测试案例,来理一理这个逻辑。

传统的Form表单提交 场景构造

如果我这里点击提交按钮,就会触发浏览器的提交功能,那结果是什么样呢?

注意点

可以看到Content-Typeapplication/x-www-form-urlencoded
值得形式是以key1=value1&key2=value2的形式提交的。

传统的ajax提交 场景构造
function submit2() {
    var xhr = new XMLHttpRequest();
    xhr.timeout = 3000;
    var obj = {a: 1, b: 2};
    xhr.open("POST", "/");
    xhr.send(obj);
}

首先我们构造一个简单的函数,然后触发它。通过chrome反馈来看:

注意点

1.默认的Content-Typetext/plain
2.Request Payload会对非字符串做字符串转换。
3.通过xhr.send(JSON.stringify(obj));可修正要发的内容

axios方式提交 场景构造

由于axios已经是vue、react的准标配请求方式了,所以这里探究一下它。
首先我门看axios的文档,当post提交时候可以传递什么类型参数:

注意这个类型,我们分别构造两个场景。对应它。

function submit3() {
    var sence1 = "name=123&val=456";
    var sence2 = {name: 123, val: 456};
    axios.post("/", sence1)
}

分别传递字符串与对象,提交post请求,然后观察结果:

场景1——传递字符串时候的结果:

场景2——传递对象的结果:

注意点

1.当我们传递字符串的时候,Content-Type自动转为xxx-form-xxx的形式。当为对象的时候,自动转化为xxx/json
2.字符串的时候以key1=val1&key2=val2的形式体现,对象以JSON字符串形式体现。

总结

探索了这么多种情况之后,那么我们回顾一下:

Content-Type的差异

1.传统的ajax请求时候,Content-Type默认为"文本"类型。
2.传统的form提交的时候,Content-Type默认为"Form"类型。
3.axios传递字符串的时候,Content-Type默认为"Form"类型。
4.axios传递对象的时候,Content-Type默认为"JSON"类型

Content-Type的值,Form与非Form时,payload的区别。

1.都只支持字符串类型(以上探究的几种情况)
2.Form需要传递的格式为key1=value1&key2=value2,类似GET请求的QueryString格式
3.非Form一般为JSON.stringify(formDataObject)形式

后端取不到值?

无论何种形式传递,后端解析表单信息的时候,会考虑Content-Type。如果是JSON字符串的话,后端解析payload的内容时候,肯定要去解析JSON啦。如果是key1=value1&key2=value2的形式,则需要去分割字符串。

当然这些事情一般后端使用的框架会去处理,但是框架给后端提供取值接口有可能是不同的,所以前端的小伙伴在处理请求问题时,一定要跟后端小伙伴商量好,是用JSON还是FormData哈。

后记

本来只是小小的一个问题,仔细研究起来发现挺多细节。今天就花时间整理了一下,希望能给大家一些帮助。码字不容易,如果感到这篇文章对你有用。点个赞,收个藏呗。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/103261.html

相关文章

  • Dva + Ant Design 前后分离 React 应用实践

    摘要:数据缓存对于一个应用来说,缓存是很重要的一步。所以,比较常见的方法就是将数据缓存在中。什么时候做数据缓存例用户信息缓存参见在中配置了检测中的是否存在。 源站链接 https://tkvern.com 继 Rails 从入门到完全放弃 拥抱 Elixir + Phoenix + React + Redux 这篇文章被喷之后,笔者很长一段时候没有上社区逛了。现在 tkvern 又回归了,给...

    tainzhi 评论0 收藏0
  • 一个HTTP打趴80%面试者

    摘要:阅读原文一个打趴面试者面试一年多,每当我问起面试者对的了解时,个个回答令我瞠目结舌,这些开发者都有年的经验。向指定资源提交数据进行处理请求例如提交表单或者上传文件。 阅读原文:一个HTTP打趴80%面试者 面试一年多,每当我问起面试者对HTTP的了解时,个个回答令我瞠目结舌,这些开发者都有3-5年的经验。请不要让我叫你野生程序员,是时候了解HTTP了,让我们当个正规军。 起因 面试官:...

    econi 评论0 收藏0
  • ajax入门

    摘要:基于标准被广泛支持。这样的类最初是在中作为一个名为的对象引入的。请求还没有被发送。当为,这个属性返回目前已经接收的响应部分。由服务器返回的状态代码,如表示成功,而表示错误。方法取消当前响应,关闭连接并且结束任何未决的网络活动。 前言 总括: 本文讲解了ajax的历史,工作原理以及优缺点,对XMLHttpRequest对象进行了详细的讲解,并使用原生js实现了一个ajax对象以方便日常开...

    Fundebug 评论0 收藏0
  • 跨域问题汇总

    摘要:因为浏览器的同源策略,前端开发会遇到各种跨域问题。前言在总结各种跨域问题之前,我们先来了解一下浏览器的同源策略。所以只能解决一级域名相同二级域名不同的跨域问题。 跨域问题的场景和解决方案多种多样,只要是做前端开发,总会遇到。而且面试时也是必问的问题。所以自己学习总结记录一下。 因为浏览器的同源策略,前端开发会遇到各种跨域问题。本篇文章总结了遇到跨域问题的不同的场景以及对应的解决方案。 ...

    MkkHou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<