Mac 备忘录 2

272 阅读12分钟

HTTP ****使用指南

1 Form****表单提交: Submitting forms and uploading files

An html

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。

6Ajax请求无法下载文件的原因

实现下载的方法

  • 隐藏表单,用提交表单的形式(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是什么意思及区别?

$@表示所有参数

$#表示所有参数的个数

取当前shell的所有参数,将所有的命令行视为单个字符串,相当于“* 取当前shell的所有参数,将所有的命令行视为单个字符串,相当于“1$2”

@取当前shell的所有参数保留参数里的空白,,相当于“@ 取当前shell的所有参数保留参数里的空白,,相当于“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 [ 1=="reids"a1 == "reids" -a 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。

你可能会发现术语生成(emittedemit)贯穿了我们整个文档和插件 API。它是“生产(produced)”或“释放(discharged)”的特殊术语。

******\

loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

在 webpack 的配置中 loader 有两个目标:

  1. test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
  2. 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: 组成块

6hashchunkhashcontenthash之间的误用 :

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 打包产生的文件名中,hashchunkhashcontenthash 的区别

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占位符配置。

**\

****\

7importrequire****的区别:

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…