当前位置: 首页 > news >正文

中小型企业网站建设与管理请举例说明什么是网络营销

中小型企业网站建设与管理,请举例说明什么是网络营销,WordPress网页小游戏,wordpress显示前3张图片一直在用组件库做文件上传#xff0c;那里面的原理到底是啥#xff0c;自己写能不能写一个upload框出来呢? #xff08;一#xff09;基本原理 浏览器端提供了一个表单#xff0c;在用户提交请求后#xff0c;将文件数据和其他表单信息编码并上传至服务器端#xff0…一直在用组件库做文件上传那里面的原理到底是啥自己写能不能写一个upload框出来呢? 一基本原理 浏览器端提供了一个表单在用户提交请求后将文件数据和其他表单信息编码并上传至服务器端服务器端将上传的内容进行解码了提取出 HTML 表单中的信息将文件数据存入磁盘或数据库。 就是编码-解码-放数据库其实。 浏览器采用默认的编码方式是 application/x-www-form-urlencoded 可以通过指定 form 标签中的 enctype 属性使浏览器知道此表单是用 multipart/form-data 方式编码如 form enctypemultipart/form-data action${pageContext.request.contextPath}/servlet/uploadServlet2 methodpost 二详解 2.1编码篇 我们在上传文件的时候用的编码都是form-data的形式不上传文件的时候都是用application/x...的格式这是为啥呢 总的来说application传输二进制文件或者非ASCII码字符的时候会对数据进行大量转义导致传输效率低下而且也不支持多文件传输。 相对的form-data的数据处理形式就比较适合传输文件他会把表单数据分成多个部分每个部分有自己的头部信息和数据内容而且还用分隔符分割数据内容可以是文本或二进制数据可以是文件或表单字段的值。他还支持多文件多表单数据的传输所以经常用他来传输文件。 但大文件上传就不用这个了用的是application/octet-stream后面再说。 2.1.1 常见的application/x-www-form-urlencoded 如果你打开network就知道很多表单提交请求都是用的application/x-www-form-urlencoded这个编码方式编码结果就是namexiaomingage18 在这种编码格式中所有字段名和值都被URL编码并使用等号分隔。每个字段之间使用与号分隔。但让他来处理数据庞大的二进制数据或者包含非 ASCII 字符的数据的时候就会显得力不从心。因为它是一种文本格式只能处理 ASCII 字符集中的字符无法处理二进制数据。在该编码格式中所有的非 ASCII 字符都需要进行编码这会导致二进制数据被大量转义使得数据量变得非常大传输效率低下。另外该编码格式也不支持多部分传输无法将多个文件或多个表单字段一起传输。因此如果需要传输二进制文件或多个表单字段应该使用其他编码格式如 multipart/form-data。该编码格式支持二进制数据和多部分传输可以更有效地传输文件和表单数据。 2.1.2 multipart/form-data 使用这个编码的时候会把表单数据分成多个部分每个部分都有自己的头部信息和数据内容。各部分之间用一个不可能出现的分隔符分隔分隔符由一个随机字符串和两个连字符组成例如–boundary。每部分都对应表单中的一个input区 这种编码方式先定义好 一个不可能在数据中出现的字符串作为分界符然后用它将各个数据段 分开而对于每个数据段都对应着 HTML 页面表单中的一个 Input 区包括一个 content-disposition 属性说明了这个数据段的一些信息如果这个数据段的内容是一个文件还会有 Content-Type 属性然后就是数据本身。 头部信息有这个部分的类型、名称和其他元数据。对于文件上传还包含了文件名和文件类型等信息。数据内容可以是文件或者表单的值。 multipart/form-data 是一种常见的编码格式用于在 HTTP 协议中传输二进制数据和多部分数据。它通常用于上传文件或提交包含多个表单字段的表单数据。 在 multipart/form-data 编码中数据被分成多个部分每个部分都有自己的头部信息和数据内容。每个部分之间用一个特殊的分隔符分隔分隔符由一个随机字符串和两个连字符组成例如–boundary。 每个部分的头部信息包含了该部分的类型、名称和其他元数据。对于文件上传头部信息还包含了文件名和文件类型等信息。数据内容可以是文本或二进制数据可以是文件或表单字段的值。 multipart/form-data 编码格式支持上传多个文件和多个表单字段可以同时上传多个文件和表单字段。它还支持断点续传和上传进度显示等功能可以更好地满足文件上传的需求。 需要注意的是multipart/form-data 编码格式会增加数据传输的开销因为每个部分都需要添加头部信息和分隔符。因此在传输大文件或大量数据时应该考虑使用其他编码格式如 application/octet-stream。 2.1.3 思考 也许你有疑问那可以用 application/json 吗 其实我认为无论你用什么都可以传只不过会要综合考虑一些因素的话multipart/form-data 更好。例如我们知道了文件是以二进制的形式存在application/json 是以文本形式进行传输那么某种意义上我们确实可以将文件转成例如文本形式的 Base64 形式。但是呢你转成这样的形式后端也需要按照你这样传输的形式做特殊的解析。并且文本在传输过程中是相比二进制效率低的那么对于我们动辄几十 M 几百 M 的文件来说是速度是更慢的。 以上为什么文件传输要用 multipart/form-data 我还可以举个例子例如你在中国你想要去美洲我们的 multipart/form-data 相当于是选择飞机而 application/json 相当于高铁但是呢中国和美洲之间没有高铁啊你执意要坐高铁去你可以花昂贵的代价后端额外解析你的文本造高铁去美洲但是你有更加廉价的方式坐飞机使用 multipart/form-data去美洲去传输文件。你图啥 为什么要编码 传递过程中要进行编码来制定发送的文件数据规则以便于后端能够实现一套对应的解析规则。传递的数据规则里包含所传递文件的基本信息 如文件名与文件类型以便后端写出正确格式的文件。 2.1.4 实践一下 如果一不小心真用这个来传文件了会怎么样 首先我们先写下最简单的一个表单提交方式。 form actionhttp://localhost:7787/files methodPOSTinput namefile typefile idfileinput typesubmit value提交 /form 我们选择文件后上传发现后端返回了文件不存在。 不用着急熟悉的同学可能立马知道是啥原因了。 我们打开控制台由于表单提交会进行网页跳转因此我们勾选 preserve log 来进行日志追踪。 我们可以发现其实 FormData 中 file 字段显示的是文件名并没有将真正的内容进行传输。再看请求头。 发现是请求头和预期不符也印证了 application/x-www-form-urlencoded 无法进行文件上传。 我们加上请求头再次请求。 form actionhttp://localhost:7787/files enctypemultipart/form-data methodPOSTinput namefile typefile idfileinput typesubmit value提交 /form 发现文件上传成功简单的表单上传就是像以上一样简单。但是你得熟记文件上传的格式以及类型。 2.2 提交的时候 在文件上载和表单提交的过程中有两个指的关心的问题一是 上载的数据是是采用的那种方式的编码这个问题的可以从 Content-Type 中得到答案另一个是问题是上载的数据量有多少即 Content-Length 知道了它就知道了 HttpServletRequest 的实例java中有多少数据可以读取出来。 2.2.1 后端不解析的话会拿到啥 在开头的时候就说了整个文件上传的流程就是表单提交-编码-解析-保存 下面的内容示范了后端不去处理上传的数据内容时会受到什么样的数据。 psform 表单提交操作网页会造成整体刷新所以一般比较少用而是利用熟悉的异步请求操作 AJAX 来完成上传动作而一个新的问题出现了不使用 form 表单那文件编码该怎么处理呢 答案是自己生成 FormData 的实例咯 const form new FormData() 然后用 form.append(file: fileData)来放数据 form methodPOST enctypemultipart/form-data input typefile namefile value请选择文件br /input typesubmit /form下面提供NodeJs示例 //上传接口逻辑 if (url /upload method POST) {// 定义一个缓存区const arr [];req.on(data, (buffer) {// 将前端传来的数据进行存储进缓存区arr.push(buffer);});req.on(end, () {// 前端请求结束后进行数据解析 处理const buffer Buffer.concat(arr);// 将数据变成string类型const content buffer.toString();// 从传来的数存进test的文件里fileStream(test).write(buffer);// 返回前端请求完成res.writeHead(200, { Content-Type: text/html; charsetutf-8 });res.end(上传完成);}); }这里的服务端代码先将前端上传的数据内容毫不处理直接写入一个名为 test 的文件内以便我们查看前端到底传来了什么样的数据。 上传上面的html文件这是前端的部分请求头。 Conten-Type中前面的是数据类型后面就是分隔符啦。 这是后端得到的数据请求体 ------WebKitFormBoundary7YGEQ1Wf4VuKd0cE Content-Disposition: form-data; namefile; filenameindex.html Content-Type: text/html// 这里是文件内容 htmlheadtitle上传文件/title/headbodyform methodPOST enctypemultipart/form-datainput typefile namefile value请选择文件br /input typesubmit/form/body /html ------WebKitFormBoundary7YGEQ1Wf4VuKd0cE--2.2.2 后端是如何解析的 从上面的示例可以看到后端拿到的请求体其实跟我上传拿到文件内容差不多但多了一些东西所以后端解析器的目的就是去掉这几行内容并且在这几行简要信息里摘出文件名以便写文件。 先是第一行和最后一行的 WebKitFormBoundary 码第二行的 ContentDisposition该行包含一些文件名等基本信息还有第三行文件内容类型所以后端如果要获取到正确的文件内容则需要自己去除直接用 indexof length substr 就可以由浏览器在上传时所添加的进来的几行内容而保留有效文件内容后进行写文件操作完成上传目的。 自己写一个解析器拆成数组然后字符串操作进行删和拿。 /*** step1 过滤第一行* step2 过滤最后一行* step3 过滤最先出现Content-Disposition的一行* step4 过滤最先出现Content-Type:的一行*/ const decodeContent content {let lines content.split(\n);const findFlagNo (arr, flag) arr.findIndex(o o.includes(flag));// 查找 ----- Content-Disposition Content-Type 位置并且删除const startNo findFlagNo(lines, ------);lines.splice(startNo, 1);const ContentDispositionNo findFlagNo(lines, Content-Disposition);lines.splice(ContentDispositionNo, 1);const ContentTypeNo findFlagNo(lines, Content-Type);lines.splice(ContentTypeNo, 1);// 最后的 ----- 要在数组末往前找const endNo lines.length - findFlagNo(lines.reverse(), ------) - 1;// 先反转回来lines.reverse().splice(endNo, 1);return Buffer.from(lines.join(\n));}一个简单的解析器完成了一般情况下你所使用的框架会解决解码这一部分问题无论是 Nodejs 或是 Java他们的本质都是摘出有效的文件内容然后写进新文件里从而达到文件上传的目的。 最终的服务器代码如下 // 最终的服务端代码 if(url /upload method POST) { //文件类型 const arr [] req.on(data, (buffer) {arr.push(buffer); }) req.on(end, () {const buffer Buffer.concat(arr);const content buffer.toString();const result decodeContent(content);const fileName content.match(/(?filename).*?(?)/)[0];fileStream(fileName).write(result);res.writeHead(200, { Content-Type: text/html; charsetutf-8 });res.end(上传完成) }) }2.2.3 不用formdata直接用file对象呢 上面那些编码的意义都是规范都是为了前后端更好地进行协作开发。 当我们遇到了无form表单的情况时该怎么上传文件。 文件上传的实质是上传文件的内容以及文件的格式当我们使用 HTML 提供的 Input 上传文件的时候它将文件的内容读进内存里那我们直接将内存里的数据当成普通的数据提交到服务端可以么 上面的代码中直接用input框的file对象写了。 然后直接跟之前提到的后端代码一样什么解析都不做直接写到txt文件里打开你就会发现这就是自己上传的文件一模一样后台解析都不用解析。 简单介绍一下file对象 用上面的代码尝试一下。 没上传任何内容打印了一下 file 变量是 undefined然后我上传了一张图片再次打印后 file 变量是一个 File 函数构造出的对象了它里面有文件的一些简略信息如大小 size文件名 name 以及文件格式 type 等而且文件内容也在这个对象里只不过以 ArrayBuffer 的方式在文件的原型链上体现看看下面对于 File 对象的操作。 上面这些数字其实就是文件的内容大家都知道数据是 01 组成的世界而 ArrayBuffer 则是更多的数字来体现的数据世界它和二进制的目的是一样的它被用来表示通用的、固定长度的原始二进制数据缓冲区。说到这里则必须要提起一个新的概念浏览器的提供的 Blob 接口。 blob对象 Blob 对象表示一个不可变、原始数据的类文件对象。上面的 file 变量的构造函数 File 就是继承与基于 Blob继承了 blob 的功能并将其扩展使其支持用户系统上的文件。看看下面的 Blob 与 File 的示例。 上面我先打印了一下 file 与浏览器提供的构造函数 File 和 Blob 的关系然后自行构建了自定义的 myfile 对象和 myblob 的对象看得出自行构建的 File 对象下会多出一些文件相关的属性而 Blob 对象则只是基本的 size 与 type 属性。当打印 arrayBuffer 函数的返回值时发现其内容也是完全一致的。 其实说到这里很多人对于 Blob 是个啥还是一知半解的简单理解一下它的构造结果是一块内存区这块内存区以特定的格式存储我们所要上传的文件二进制数据当我们上传文件时上传这块内存区里的数据即可。 参考文章1 参考文章1
http://www.dnsts.com.cn/news/231708.html

相关文章:

  • 南通市港闸区城乡建设局网站线上广告投放渠道
  • 建网站网络公司企业所得税法实施条例
  • asp.net网站开发pdf衡水哪家制作网站好
  • 苏州专业建站签名设计网站
  • 海外网站加速器下载学做电商网站
  • 新塘做网站公司天津搜索引擎推广
  • 公司网站设计制作搜狗官网
  • 重庆工信部网站做网站公司的商标需要注册吗
  • 仿系统之家网站源码响应式网站建设准备
  • 深度网营销型网站建设公司怎么样网络营销外包专员
  • 广发证券 网站谁做的seo网站推广专员招聘
  • 律师个人网站建设做视频网站需要多大的带宽
  • 国内做任务得数字货币的网站长沙做网站哪家公司好
  • 网站本科报考官网安徽工程建设发展有限公司
  • 商务网站建设策划书汽车网站建设的基本功能
  • 帮客户做网站的公司dedecms 网站地图模板
  • 深圳做棋牌网站建设哪家好太原做微网站的公司
  • 郑州网站+建设区域网站怎么做
  • 软件开发流程示意图手机优化软件下载
  • 企业网站源码 企业网站管理系统管理网站开发教程
  • html网站开发视频网络推广的方法有哪几种
  • 淮南招投标信息网广州网站优化方案
  • 网站后台管理系统 源码做网络歌手的网站
  • 简述网站建设的具体步骤不用下载qq在线qq登录聊天
  • 免费商城网站系统小网站怎么搜关键词
  • 中铁建设集团门户网站企业做可信网站认证的好处
  • 建行网站登录不了中国交通建设集团有限公司英文名
  • 商业网站设计欣赏家装装饰设计
  • 网站建设菜鸟教程简述建设电子商务网站步骤
  • 如何理解电子商务网站建设与管理网站建设功能需求文档