HTTP ****使用指南
1 、 Form****表单提交: Submitting forms and uploading files
can be sent in four ways:- using the POST method and setting the enctype attribute to application/x-www-form-urlencoded (default);
- using the POST method and setting the enctype attribute to text/plain;
- using the POST method and setting the enctype attribute to multipart/form-data;
- using the GET method (in this case the enctype attribute will be ignored).
****\
enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。如果使用post请求,请求头中的content-type指定值就是该值enctype.
Post请求下的Content-Type类型(编码类型)
值 | 描述 |
application/x-www-form-urlencoded | 在发送前编码所有字符(默认)。(空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值) |
multipart/form-data | 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。 |
text/plain | 空格转换为 "+" 加号,但不对特殊字符编码。 |
相比之下, get方式的数据提交方式(编码方式)只有一种,就是application/x-www-form-urlencoding;charset=utf-8 。
****\
浏览器提交表单(触发表单submit事件)时,会执行如下步骤:
1、识别出表单中表单元素的有效项,作为提交项
2、构建一个表单数据集(FormData?)
3、根据form表单中的enctype属性的值作为content-type对数据进行编码
4、根据form表单中的action属性和method属性向指定的地址发送数据
2 、 Ajax提交
ajax提交文件:
1、最初,ajax出于安全性考虑,不能对文件进行操作,所以就不能通过ajax来实现文件上传,但是通过隐藏form提交则可以实现这个功能,所以这也是用隐藏form提交的主要用途。
2、后来XMLHttpRequest引入了FormData类型,它是为序列化表以及创建与表单格式相同的数据提供的。使得通过Ajax也可以实现文件上传。目前几乎所有的主流的浏览器都已经支持这个对象了。
代码:
let formData = new FormData();
或者基于表单 let formData = new FormData(document.querySelector(“#form_id”))
formData.append("file", document.querySelector(“input[type=file]”));
utils .ajax({
url: url,
method: "post",
data: formData,
headers: { "Content-Type": "multipart/form-data" }
})
ajax****促进的编码方式:
application/json
application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。
Content-type: application/json ; charset=utf-8 designates the content to be in JSON format , encoded in the UTF-8 character encoding.
Google 的 AngularJS 中的 Ajax 功能,Content-Type默认就是提交 JSON 字符串。当指定Content-type: application/json; 时,默认编码就是utf-8,不需要额外指定。
JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」
数据提交方式差异: form表单并不支持application/json格式提交数据,但是我们可以拦截form表单submit提交,改为ajax提交表单序列化的JSON数据。
$(':submit').on('click',function(){
$.ajax({
url:"buy",
type:"POST",
data:JSON.stringify($('form').serializeObject()),
contentType:"application/json", // 缺失会出现URL编码,无法转成json对象
success:function(){
alert("成功");
}
});
});
3 、 Http****协议行为
我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:
- 状态行
- headers 请求头
- entity-body 消息主体
协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。
但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。
所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。
新型流行Content-Type:
4 、 Form VS Ajax, $http (www.cnblogs.com/lidgblogs/p… )
1 、 提交方式
form表单通常是通过在HTML中定义的action,method及submit来进行表单提交,另外也可以通过在js中调用submit函数来进行表单提交。
具体的提交方式有很多种,比如可以通过封装成XMLHttpRequest对象进行提交,这里就不一一详述了。
而另外两种请求(Ajax,$http)都是基于XMLHttpRequest进行的。
2、页面刷新
Form提交,更新数据完成后,需要转到一个空白页面再对原页面进行提交后处理。哪怕是提交给自己本身的页面,也是需要刷新的,因此局限性很大。
Ajax,$http都可以实现页面的局部刷新,整个页面不会刷新。
3、请求由谁来提交
Form提交是浏览器完成的,无论浏览器是否开启JS,都可以提交表单。
Ajax,$http是通过js来提交请求,请求与响应均由js引擎来处理,因此不启用JS的浏览器,无法完成该操作。
4、是否可以上传文件
最初,ajax出于安全性考虑,不能对文件进行操作,所以就不能通过ajax来实现文件上传,但是通过隐藏form提交则可以实现这个功能,所以这也是用隐藏form提交的主要用途。
后来XMLHttpRequest引入了FormData类型,使得通过Ajax也可以实现文件上传,稍后会详细介绍。
5 、 MIME
"Multipurpose Internet Mail Extensions"多功能Internet邮件扩充服务,它是一种多用途网际邮件扩充协议。
1.作用
服务器会将它们发送的多媒体数据的类型告诉浏览器,而通知手段就是说明该多媒体的MIME类型,从而让浏览器知道接受到的信息哪些是MP3,哪些是Shockwave文件等等。
服务器将MIME标识符放入传送的数据中来告诉浏览器使用哪个插件读取相关文件
对于text文件类型若没有特定的subtype,就使用 text/plain。类似的,二进制文件没有特定或已知的 subtype,即使用 application/octet-stream。
6、Ajax请求无法下载文件的原因
实现下载的方法
- 隐藏表单,用提交表单的形式(blog.csdn.net/qq_42864616…)
- 用window.open() 或 window.location.href=”下载地址“
- 创建iframe,iframe的src可以是文件地址url来直接下载文件
1.使用ajax,ajax的返回值类型是json,text,html,xml类型,或者可以说ajax的发送,接受都只能是string字符串,不能流类型,所以无法实现文件下载,强用会出现response冲突。
如果非要使用ajax的话,只能通过返回值得到生成的文件相关url。然后在回调函数里通过创建一个iframe,并设置其src值为文件url,或者一个对文件生成流的处理url,这样操作来实现文件下载且页面无刷新。
2.不使用ajax,通过dom动态操作或创建iframe,form的方式来实现,在下载文件的同时实现页面不刷新,其中iframe的src可以是文件地址url来直接下载文件,也可以是流处理url通过response流输出下载,form的是流处理url通过response流输出下载,dom动态操作的时候实现文件下载,且页面无刷新。
要在下载的同时实现进度条的话,可以创建一个定时任务,每隔一定时间就向后台发送请求,通过公用的对象,比如session,来取得文件下载的处理进度。
Linux命令
1 、 Linux shell 脚本中, @ \* 和 $# 分别是什么意思?#!/bin/bash和#!/bin/sh是什么意思及区别?
$@表示所有参数
$#表示所有参数的个数
1$2”
1“,”$2”,这是将参数传递给其他程序的最佳方式。
$1 取第一个参数。
#!是特殊的标识符,其后面跟的是解释次脚本的shell的路径。
#!/bin/sh 是指此脚本使用使用/bin/sh来解释执行。 #!/bin/bash同理。
#!/bin/sh 和 #!/bin/bash虽然大体上没什么区别,但仍然存在不同的标准,可以说sh是bash的缩减版。
\
2 、 linux alias****如何传参数?
alias 只会按顺序展开,参数不会起作用,最好的办法是用function,如果硬要用alias,可以像这样跟function组合:
alias zhouchun='function __zhouchun() { echo "scp $* j"; unset -f __zhouchun; }; __zhouchun'
这个function在用过后会自己unset,不会留下多余的东东,而只有你的alias会起作用。
~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当登录时以及每次打开新的shell时,该文件被读取.
~/.bashrc:该文件包含专用于你的bash shell的bash信息,每个用户都有一个.bashrc文件,在用户目录下。
Linux unset命令用于删除变量或函数。
unset为shell内建指令,可删除变量或函数。
unset [-fv][变量或函数名称]
参数:
- -f 仅删除函数。
- -v 仅删除变量。
3 、 uname -a 命令查看到我的Linux系统位数是64位(备注:x86_64表示64位系统, i686 i386表示32位系统)
4 、后台方式启动程序:后面加 & 符号,如 : redis-server &
非后台启动程序后想退出:exit
5、在Linux上编译安装软件时,经常遇到 ./configure –prefix=/usr/local/xx 这个命令。
Linux源码的安装一般由有这三个步骤:配置(configure)、编译(make)、安装(make install)。
Configure是一个可执行脚本,它有很多选项,在待安装的源码路径下使用命令./configure –help输出详细的选项列表。其中–prefix选项就是配置安装的路径。
如果不配置该选项,安装后可执行文件默认放在 /usr /local/bin ,库文件默认放在 /usr/local/lib ,配置文件默认放在 /usr/local/etc ,其它的资源文件放在 /usr /local/share ,比较分散。
为了便于集中管理某个软件的各种文件,可以配置–prefix,如:
./configure –prefix=/usr/local/mongodb
可以把软件安装结果所有资源文件放在/usr/local/mongodb的路径中,就不会分散了。
用了—prefix选项的另一个好处是卸载软件或移植软件。当某个安装的软件不再需要时,只须简单地删除该安装目录,就可以把软件卸载得干干净净;移植软件只需拷贝整个目录到另外一个机器即可(相同的操作系统)。
当然要卸载程序,也可以在原来的make目录下用一次make uninstall,但前提是make文件指定过uninstall。
6、今天在Ubuntu服务器上安装supervisor,部署没成功想卸载重来,sudo apt-get remove supervisor 后发现配置文件还在,便手动删除了配置文件。
查阅资料才知,还有 apt-get purge 这一选项,purge 清除。
apt-get remove 会删除软件包而保留软件的配置文件
apt-get purge 会同时清除软件包和软件的配置文件。 apt-get purge -y python.*
7、linux下查看所有用户及所有用户组
groups 查看当前登录用户的组内成员
groups gliethttp 查看gliethttp用户所在的组,以及组内成员
whoami 查看当前登录用户名
/etc/group文件包含所有组
/etc/shadow和/etc/passwd系统存在的所有用户名
8、执行xx.sh文件报permission denied时,
解决一:1、加执行权限 chmod +x xx.sh 解决二:sudo sh xx.sh
9、[: too many arguments 提示或报错解决:
原写法:if [ 2 == "port" ] // 导致提示,原因 :空格回车等迷惑了bash
改写成: if [[ 1 == "reids" && 2 == "port" ]]
node内存溢出解决: 在node_modules.bin\ webpack-dev-server 修改内存可以规避webpack编译出现内存溢出问题 node --max-old-space-size=10240
Webpack 4
1、本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
理解四个核心概念:
- 入口(entry)
- 输出(output)
- loader
- 插件(plugins)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。默认值为 ./src。
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。
你可能会发现术语生成(emitted 或 emit)贯穿了我们整个文档和插件 API。它是“生产(produced)”或“释放(discharged)”的特殊术语。
******\
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
在 webpack 的配置中 loader 有两个目标:
- test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
- use 属性,表示进行转换时,应该使用哪个 loader。
e.g.
module: {
rules: [
{ test: /.txt$/, use: 'raw-loader' }
]
}
“嘿,webpack 编译器,当你碰到「在 require()/import 语句中被解析为 '.txt' 的路径」时,在你对它打包之前,先使用 raw-loader 转换一下。”
2、插件(plugins)
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
想要使用一个插件,你只需要 require() 它,然后使用 new 操作符来创建它的一个实例,把它添加到 plugins 数组中。你也可以在一个配置文件中因为不同目的而多次使用同一个插件。
e.g.
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
3、模式
通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化
module.exports = {
mode: 'production'
};
4 、常用插件
1、CommonsChunkPlugin
通过将多个入口 chunk 的公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存到缓存中供后续使用。这个带来页面速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。
你必须在 入口chunk 之前加载生成的这个 公共chunk。
2、extract-text-webpack-plugin插件主要是为了抽离css样式,防止将样式打包在js中引起页面样式加载错乱的现象。
该插件会默认将入口文件中直接或间接引入(require或import)的所有css抽取到一个单独的CSS文件,对于按需加载(require.ensure()和import())函数的模块不会抽取出来,需要配置allChunks:true。
在使用web-dev-server的时候,不要使用extract-text-webpack-plugin,目前不支持。
3、CommonsChunkPlugin主要是用来提取第三方库和公共模块,避免首屏加载的bundle文件或者按需加载的bundle文件体积过大,从而导致加载时间过长,着实是优化的一把利器。
这时候的vendor.js就纯白无瑕,只包含第三方库文件,common.js就是自定义的公共模块,runtime.js就是webpack的运行文件。
5 、 output.filename 与 output.chunkFilename 的区别
output.filename: 此选项决定了entry入口文件输出 bundle 的名称。注意,此选项不会影响那些「按需加载 chunk」的输出文件。对于这些文件,请使用 output.chunkFilename 选项来控制输出。
output.chunkFilename: 此选项决定了非入口(non-entry) chunk 文件的名称。默认使用 [id].js 或从 output.filename 中推断出的值([name] 会被预先替换为 [id] 或 [id].
翻译: bundle: 捆绑包 chunk: 组成块
6、hash、chunkhash、contenthash之间的误用 :
chunkhash是随着某一特定chunk的内容变化而变化,即根据某个特定chunk的内容计算出的hash值。
chunkhash和hash不一样,它根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。
hash是随着compilation进行而产生,每次编译生成一个唯一hash,但所有资源全打上同一个 hash,无法完成持久化缓存的需求。
extract-text-webpack-plugin提供了另外一种hash值:contenthash。顾名思义,contenthash代表的是文本文件内容的hash值,也就是只有style文件的hash值。
不要在开发环境使用 ****[ chunkhash ] / [ hash ] / [ contenthash ],因为不需要在开发环境做持久缓存,而且这样会增加编译时间,开发环境用 ****[ name ] ****就可以了。
webpack 打包产生的文件名中,hash、chunkhash、contenthash 的区别
hash 类型 | 区别 |
hash | 每一次打包都会生成一个唯一的 hash |
chunkhash | 根据每个 chunk 的内容来生成;chunk打包时,output.filename、output.chunkFilename 推荐使用 chunkhash。 |
contenthash | 根据提取文件的内容生成的 hash;在使用 ExtractTextWebpackPlugin(webpack 3.x)或MiniCssExtractPlugin(webpack 4.x)时,使用 contenthash 提取出css部分代码到单独的css文件(比如:vue单文件组件中的style部分) 注意:只有使用上面内容提取插件的内容才支持contenthash占位符配置。 |
**\
****\
7、import和require****的区别:
node编程中最重要的思想就是模块化,import和require都是被模块化所使用。
遵循规范
- require 是 AMD规范引入方式
- import是es6的一个语法标准,如果要兼容浏览器的话必须转化成es5的语法
调用时间
- require是运行时调用,所以require理论上可以运用在代码的任何地方
- import是编译时调用,所以必须放在文件开头
本质
- require是赋值过程,其实require的结果就是对象、数字、字符串、函数等,再把require的结果赋值给某个变量。新增require.ensure()动态加载。
- import是解构过程,但是目前所有的引擎都还没有实现import,我们在node中使用babel支持ES6,也仅仅是将ES6转码为ES5再执行,import语法会被转码为require
- 两个按需加载函数import()函数,require.ensure()函数,即用到了再加载,完成动态加载。
除此之外,本质上:
CommonJS 还是 ES6 Module 输出都可以看成是一个具备多个属性或者方法的对象
ES6 Module 中导入模块的属性或者方法是强绑定的,包括基础类型;而 CommonJS 则是普通的值传递或者引用传递。
8 、 webpack****详细插件列表官方文档地址: www.webpackjs.com/plugins/com…