首页 > 其他分享 >这一次,弄明白JS中的文件相关(二):HTTP请求头和响应头

这一次,弄明白JS中的文件相关(二):HTTP请求头和响应头

时间:2024-01-23 18:11:33浏览次数:27  
标签:文件 HTTP 请求 application JS Content 响应 Type

(一)前置知识

开始前,我们先来复习一下HTTP的基础知识。

HTTP请求分为:请求行、请求头、空行、请求体(也叫正文、请求实体、请求主体)。

HTTP响应分为:状态行(也叫响应行)、响应头、空行、响应体(也叫正文、响应实体、响应主体)。

在HTTP请求中,最常见的GET请求是没有请求体的(GET的查询字符串不属于请求体),只有POST、PUT请求有请求体。

在HTTP响应中,大部分时候都会有响应体,什么情况会没有呢?

状态码为1xx、204 No Content、301、302重定向、304 Not Modified的响应。还有一个,就是HEAD方法的响应,HEAD和GET的区别,是只返回头部信息,不返回实体数据。

我们今天要讨论的HTTP中文件相关的字段,就是指的请求体和响应体(统称为实体)相关的字段。

 

(二)请求体和响应体相关的字段

1. 数据类型:实体的MIME类型。

Accept:请求头字段,标记客户端可理解的MIME类型,写法如:Accept: text/html,application/xml,image/webp。

Content-Type:通用字段,请求头和响应头都可以用,只要有实体数据,就应该设置正确的Content-Type,没有的话就不需要。Content-Type的数据格式是:数据类型+字符集,比如:application/json;charset=UTF-8。作为请求头时,一般不需要后面的字符集。作为响应头时,当响应体为文本类型时,应该指定字符集。

2. 编码类型:实体的压缩格式,比如gzip, deflate, br。服务器可以通过对数据进行压缩,来减小响应数据的大小。

Accept-Encoding:请求头字段,标记客户端支持的压缩格式,写法如:Accept-Encoding: gzip, deflate, br。

Conent-Encoding:响应头字段,响应体的实际压缩格式,写法如:Content-Encoding: gzip。

3. 语言类型,指的是实体的自然语言,比如汉语、英语等。

Accept-Language:请求头字段,标记客户端可理解的自然语言,写法如:Accept-Language: zh-CN, zh, en。

Content-Language:响应头字段,响应体的实际自然语言,写法如:Content-Language: zh-CN。

4. 字符集,指的是实体的字符集。

Accept-Charset:请求头字段,写法如:Accept-Charset: gbk, utf-8。

这儿要注意,没有对应的响应头字段,响应体的数据类型和字符集,都在Content-Type响应头中。

5. 资源处理方式

Content-Disposition:响应头字段,指示客户端应以何种方式处理响应体数据,是显示(inline)还是下载附件(attachment),写法如:Content-Disposition: attachment; filename="example.pdf"。

6. 数据长度

Content-Length:通用字段。不管对于客户端还是服务端,知道明确的Content-Length,都是有好处的。响应头中的Content-Length更为常见,因为它可以帮助客户端优化加载速度、判断响应是否完整以及何时可以安全关闭连接。

7. 分块传输和范围请求

Transfer-Encoding、Range、Accept-Ranges、Content-Range这些暂不讨论。

有的字段,我们在平时的开发中几乎没用过,感知不到它们的存在,原因很可能是:浏览器和现代框架,会帮助我们自动处理。

 

 

我们来重点说一下:Content-Type。

(三)Content-Type请求头:

Content-Type请求头最常用的三个值是:application/x-www-form-urlencoded、multipart/form-data、application/json。还有一些其他值,比如text/plain、text/xml、application/octet-stream等,一般是在发送特定数据格式时使用,用的不多。

application/x-www-form-urlencoded和multipart/form-data这两位起源于HTML表单提交,后来在ajax请求中继续沿用。application/json则是从ajax时代开始流行。所以早期的ajax库如jquery,默认的post数据格式是application/x-www-form-urlencoded,而现代ajax库如axios,默认的数据格式就变成了application/json。

1.application/x-www-form-urlencoded:

这是form表单的默认post提交方式,将字段名和值进行URL编码,得到这种格式:a=1&b=2&c=3。你一定感觉很熟悉,没错,和url的查询字符串长一个样。这种提交方式适用于简单的文本数据,同样也是jquery.ajax的默认post请求方式。

2.multipart/form-data:

当需要上传文件时,不管是通过表单提交,还是各种ajax框架,都需要使用这种提交方式。因为这种格式能够携带二进制数据,比如文件。

3.application/json:

现代ajax框架,普遍默认采用这种post方式,比如axios,它post请求的默认数据格式就是这个。

 

(四)Content-Type响应头:

相比请求头主要是3个值,Content-Type响应头的值就丰富多了,浏览器根据响应体的数据类型,来做出不同的处理。

比如最常见的网页是text/html,api接口数据是application/json,图片是image/jpeg, image/png, image/gif,css文件是text/css等。

这里面比较特别的就是application/octet-stream,意思是不明类型的二进制数据,浏览器对它的处理方式一般是直接下载。

在nodejs中,如果使用原生的http模块,你需要手动设置Content-Type。但如果使用web框架,比如Express、koa2,如果你不设置,它们会根据内容自动推断并设置一个合适的Content-Type。在nginx等HTTP服务器中,也是会自动添加静态文件的Content-Type,它们内部通常有一张mime类型和文件扩展名的映射表。

 

(五)文件下载

我们来专门说一下文件下载:

我们工作中大多数HTTP请求,浏览器对于文件的处理方式,都是打开或直接使用,而不是下载。前端和后端,分别可以通过各自的方式来让浏览器下载文件。

1. 前端使用<a href="文件URL" download="自定义文件名">下载文件</a>,只要给a标签添加download属性,就无需管响应头的Conent-Type是什么,都可以点击下载文件,还可以指定下载的文件名。

2. 后端把Content-Type响应头设为:application/octet-stream。这种方式,实际上是把文件标记为不明类型的二进制数据,浏览器通常采用下载的方式处理这种数据。

3. 后端设置正确的Content-Type响应头,然后设置Content-Disposition: attachment; filename="example.pdf"。

Content-Disposition是专门指示浏览器如何处理响应体的内容,被浏览器显示(inline)还是作为附件下载(attachment)。可以看出,Content-Disposition是专门处理文件下载的,这才是服务端指定文件下载的最佳实践。

 

(六)文件上传

再来说一下文件上传,在web开发中,文件上传经历了从传统表单提交到使用AJAX技术的演变。

表单时代,我们通过<form method="post" enctype="multipart/form-data">来上传文件。

在前端,出于安全考虑,JS没有文件系统的权限,所以我们无法通过编程的方式创建文件,<input type="file" />是唯一的文件获取方式。

我们选中的文件,在JS中就是File对象。文件上传,就是把File对象通过表单提交或ajax发送给后端。

那么ajax时代,我们已经很少使用表单了,上传文件应该怎么写呢?

先考一下你,File对象可以作为一个普通对象的属性值吗?

答案是:不可以。因为对象的属性和值都必须是可序列化的数据,比如简单类型或对象,而File或Blob不是简单可序列化的数据。也就是说,JSON和键值对都不支持二进制数据,只有multipart/form-data这种数据格式支持。

我曾经以为,可以通过这种把File挂在普通对象的方式,作为post的请求的参数,来上传文件。由于以上的原因,这样是行不通的。

现在我们一般很少用表单了,如何存放二进制数据呢?此时我们需要一个新的数据结构:FormData。

FormData是HTML5引入的一个API,它允许我们将表单数据以键值对的形式组织起来,并且可以方便地添加文件内容,它可以模拟表单提交。具体这么写:

// XHR上传文件
// 获取文件输入元素
var fileInput = document.getElementById('fileInput');
var file = fileInput.files[0];

// 创建XMLHttpRequest实例
var xhr = new XMLHttpRequest();
xhr.open('POST', '/api/upload', true);
xhr.onload = function () {
  if (xhr.status === 200) {
    console.log('文件上传成功:', xhr.responseText);
  } else {
    console.error('文件上传失败:', xhr.statusText);
  }
};

// 设置请求头,对于文件上传,通常不需要手动设置Content-Type
// 因为在使用FormData时,浏览器会自动设置
// xhr.setRequestHeader('Content-Type', 'multipart/form-data');

// 创建FormData对象
var formData = new FormData();
formData.append('file', file);

// 发送请求
xhr.send(formData);
// axios上传文件
// 获取文件输入元素
var fileInput = document.getElementById('fileInput');
var file = fileInput.files[0];

// 创建FormData对象
var formData = new FormData();
formData.append('file', file);

// 使用axios上传文件
axios.post('/api/upload', formData, {
  // axios会自动处理FormData的Content-Type
  // 无需手动设置
})
.then(response => {
  console.log('文件上传成功:', response.data);
})
.catch(error => {
  console.error('文件上传失败:', error);
});

 

以上是对HTTP请求头和响应头中实体字段的总结,重点说明了Content-Type以及文件下载和上传。

标签:文件,HTTP,请求,application,JS,Content,响应,Type
From: https://www.cnblogs.com/luzeyu/p/17983069

相关文章

  • 如何进行H.265视频播放器EasyPlayer.js的中性化设置?
    H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,可支持H.264与H.265编码格式,性能稳定、播放流畅,能支持WebSocket-FLV、HTTP-FLV,HLS(m3u8)、WebRTC、fmp4等格式的视频流,并且已实现网页端实时录像、在iOS上实现低延时直播等功能......
  • 二、nextjs API路由如何做好JWT登录鉴权、身份鉴权,joi字段校验,全局处理异常等(c-shoppi
    介绍在这篇文章中,我们将学习如何在C-Shopping电商开源项目中,基于Next.js14,处理所有API路由中添加身份验证和错误处理中间件的思路与实现。这篇文章中的代码片段取自我最近开源项目C-Shopping,完整的项目和文档可在https://github.com/huanghanzhilian/c-shopping地址查看。Next.js......
  • 如何进行H.265视频播放器EasyPlayer.js的中性化设置?
    H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,可支持H.264与H.265编码格式,性能稳定、播放流畅,能支持WebSocket-FLV、HTTP-FLV,HLS(m3u8)、WebRTC、fmp4等格式的视频流,并且已实现网页端实时录像、在iOS上实现低延时直播等功能......
  • 安防视频监控EasyCVR平台HTTP-FMP4播放协议在分屏播放时的性能优化
    安防视频监控EasyCVR平台兼容性强,可支持的接入协议众多,包括国标GB28181、RTSP/Onvif、RTMP,以及厂家的私有协议与SDK,如:海康ehome、海康sdk、大华sdk、宇视sdk、华为sdk、萤石云sdk、乐橙sdk等。平台能将接入的视频流进行汇聚、转码与多格式分发,具体包括:RTMP、RTSP、HTTP-FLV、WebSo......
  • linux ubuntu安装 tomocat+jsp
    ubuntu20.04+jsp+tomcatjsp的运行是需要java环境的,1.安装java环境挑选java版本并安装:输入:javac查看jdk  输入java,查看jre版本当前可以选择的java有三个版本。假定选择openjdk-8;sudoaptinstallopenjdk-8-jdk#在线安装find/-typef-namejava #查找ja......
  • 安防视频监控EasyCVR平台HTTP-FMP4播放协议在分屏播放时的性能优化
    安防视频监控EasyCVR平台能将接入的视频流进行汇聚、转码与多格式分发,具体包括:RTMP、RTSP、HTTP-FLV、WebSocket-FLV、HLS、WebRTC、fmp4等。近期我们在视频监控管理平台EasyCVR系统中新增了HTTP-FMP4播放协议,有用户反馈使用FMP4协议在分屏播放时第一路出现播放不了的情况。测试发......
  • vue2项目使用jsencrypt.js实现分段加密解密
    安装:npminstall jsencrypt安装:npminstall js-base64组件:demo.vue<template></template><script>import{SM4Encrypt,SM4Decrypt}from'@/assets/des.js'importtestImportJsonfrom'@/assets/data.json'exportdefault{......
  • 如何在 Ubuntu 20.04 上安装 Node.js 和 npm
    如何在Ubuntu20.04上安装Node.js和npm2020-05-15106752版权 简介: 本文我们主要为大家介绍在Ubuntu20.04上安装Node.js和npm的三种不同的方式。镜像下载、域名解析、时间同步请点击 阿里巴巴开源镜像站一、概述Node.js是一个跨平台的JavaScript运......
  • 通过esxtop命令杀死在VC中无响应卡死的虚拟机
    通过esxtop命令杀死在VC中无响应卡死的虚拟机 有时,在vCenter中,虚拟机有时会因为各种原因出现不能管理即不能打开控制台的现象,可以通过esxtop命令来杀掉虚拟,使其恢复关机状态。如下图,假设xp2虚拟机处于假死状态:首先打开该ESXi主机的SSH服务,然后通过Putty(esxtop命令在SecureCRT中会......
  • jsgrid多个自定义控件按钮?
    我想添加多个自定义控件按钮,这样我就可以向这些按钮添加一个自定义单击事件。我遇到的问题是删除按钮只显示出来。我希望编辑和删除按钮都显示在每一行。我有以下代码:<script>$(document).ready(function(){$("#jsGrid").jsGrid({height:"auto",......