├── .DS_Store ├── .gitattributes ├── .gitignore ├── 1-git ├── 1.git的配置和常用命令.md ├── 2.合作开发及其冲突.md ├── 3.版本回滚.md ├── 4.理解CRLF,LF以及git对它的标准化设置.md ├── 5.git 常见问题.md ├── 6.如何遴选单个文件.md ├── 7.如何回滚远端仓库.md ├── 8.如何搭建git服务端.md ├── 9.如何抛弃本地最新未提交的commit.md ├── A.如何合并单个文件.md ├── B.commit评论写错了怎么修改?.md ├── C.git代理.md ├── D.git子仓库.md └── E.如何暂存正在编辑的代码.md ├── 2-gulp ├── 1.gulp入门.md ├── 2.mock数据.md ├── 3.模块化.md ├── 4.css自动添加前缀.md ├── 5.gulp异步任务转同步.md └── demo │ ├── angular.js │ ├── dataBase.json │ ├── gulpfile.js │ ├── index.html │ └── package.json ├── 3-angularJS-part1 ├── 1.angularJS-指令以及$scope的介绍.md ├── 2.angularJS-内置过滤器.md ├── 3.angularJS-自定义过滤器.md ├── 4.angularJS-内置服务.md ├── 5.angularJS-自定义服务.md ├── 6.angularJS-自定义指令.md ├── 7.angularJS-$q.md ├── 8.angularJS-ngroute.md ├── 9.angularJS-ngroute传参.md ├── A.angularJS-ngroute-Events.md ├── B.angularJS-ui-router.md ├── C.angularJS-ui-router-events.md ├── D.angularJS-ui-router传参.md └── E.angularJS-内置事件.md ├── 4-angularJS-part2 ├── 1.angularJS自定义事件.md ├── 2.my-click.md ├── 3.集成bootStrap.md ├── 4.$watch的使用.md ├── 5.angular-api.md ├── 6.集成ionic1.x.md ├── 7.$style和移动端点击事件的封装.md ├── 8.ionic轮播图实例.md └── 9.移动端手势初探.md ├── README.md ├── angularJS-tab切换 ├── README.md ├── gulpfile.js ├── index.html ├── js │ └── angular.min.js ├── package.json └── tab.html ├── demos └── 多级联动筛选demo │ └── selectfunc.js ├── nrm └── nrm.md ├── 端口号被占用如何解决.md ├── 设计模式 └── 1.单例设计模式.md └── 跨域问题 ├── iframe+window.name ├── READEME.md ├── axios.js ├── empty │ └── proxy.html ├── index.html ├── package-lock.json ├── package.json ├── server.js ├── yarn-error.log └── yarn.lock └── jsonp ├── app └── index.html └── server └── data.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PsChina/angularJS/e517c565b3f3a4e2cc220af6ff076337b6e61d78/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=JavaScript 2 | *.css linguist-language=JavaScript 3 | *.html linguist-language=JavaScript -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_module 2 | node_modules 3 | */node_modules 4 | */*/node_modules -------------------------------------------------------------------------------- /1-git/1.git的配置和常用命令.md: -------------------------------------------------------------------------------- 1 | # Git 是用来做合作开发以及版本管理的工具他的同类产品还有svn等 2 | 3 | 4 | 这次课程我们需要: 5 | 6 | 1.GitHub帐号 (http://www.github.com/) 7 | 注册github账号 8 | 激活邮箱 9 | 10 | 2.本地安装git 11 | 去git官网下载git 12 | 安装 13 | 14 | windows系统: https://git-scm.com/download/win 15 | mac系统: https://git-scm.com/download/mac 16 | 17 | # 目标 18 | 19 | 创建本地远端同步仓库 实现 提交 拉取 操作的练习 20 | 21 | 22 | # 步骤:(在本地 新建一个空文件夹 克隆远端仓库) 23 | 24 | 25 | ## 1新建文件夹 26 | 27 | 1.打开本地git (右击鼠标点击Git Bash Here) (mac系统打开终端即可) 28 | 29 | 2.cd 到这个文件夹 30 | 31 | 3.之后准备克隆远端仓库 (等待后续操作完成再回过头来克隆) wating... 32 | 33 | 34 | 35 | ## 2连接github 36 | 37 | 通过ssh连接 38 | 39 | 40 | ### 1) 41 | 42 | ssh-keygen -t rsa -C "yourEmail@yourEmail.com" 可以一路回车新建ssh key 43 | 44 | 45 | ### 2) 46 | 47 | 将ssh可以写入github 48 | 49 | 找到 ssh 50 | 51 | C:\Users\Administrator\\.ssh 下面的id_rsa.pub 用 vscode 打开 复制一下 (mac 系统在 ~/.ssh) 或者用 vi 命令查看也可以 `vi C:/Users/Administrator/.ssh/id_rsa.pub` 或者 `vi ~/.ssh/id_rsa.pub` 52 | 53 | 打开 github 登录你的的账户 54 | 55 | 找到 settings –> SSH and GPG keys -> new SSH keys -> 56 | 57 | 填写 title 和粘贴你已经复制好的 ssh key –> Add SSH key 58 | 59 | 60 | ### 3) 61 | 62 | 验证是否连接成功 63 | 64 | ssh -T git@github.com 65 | 66 | 如果 SSH and GPG keys 里面的钥匙由黑灰色变为了绿色就 说明能够正常连接 否则不能正常连接上github 67 | 68 | 69 | ## 3.新建仓库: 70 | 71 | ### 3.1 新建远程仓库 72 | 73 | https://github.com/new 74 | 75 | 填写 76 | 77 | Repository name 78 | Description 79 | 80 | 选择 81 | 82 | · Public 83 | 84 | 勾选 85 | 86 | √ Initialize this repository with a README 87 | 88 | 好完毕 89 | 90 | ### 3.2 新建本地仓库 git init 命令 91 | 92 | 1、在本地新建一个文件夹用于新项目 93 | 94 | 2、打开命令行 cd 到该文件夹或者用 vscode 打开这个文件夹在文件夹中右键选择在集成终端打开 95 | 96 | 3、在终端输入命令 git init 回车。 97 | 98 | 99 | ## 4.在git命令行克隆这个远端仓库 git clone git@github.com:PsChinaTest/gitTest.git 100 | 101 | 这个地址来自: 102 | 打开github 登录你的的账户 找到 Your repositories -> 你要克隆的仓库 -> clone or download 103 | 104 | 105 | # 命令 106 | 107 | 108 | ## git clone (克隆远端仓库) 109 | 110 | 语法 : 111 | 112 | git clone yourRepositoriesAddress(ssh/https) 113 | 114 | 例子 : 115 | 116 | git clone git@github.com:PsChina/angularJS.git 117 | 118 | 119 | ## git add (将工作区的文件添加到暂存区) 120 | 121 | 语法 : 122 | 123 | git add yourfileNameExp 124 | 125 | 例子 : 126 | 127 | git add index.html 128 | 129 | git add . 130 | 131 | . 是正则表达式 意思是匹配所有文件 132 | 133 | 134 | ## git commit (将暂存区的文件提交到本地版本库) 135 | 136 | 语法 : 137 | 138 | git commit -m '描述你提交的内容' 139 | 140 | 例子 : 141 | 142 | git commit -m '修复了某某bug/新建了XX文件' 143 | 144 | ## git commit --amend (将本次提交与上次提交合并) 145 | 146 | 语法 : 147 | 148 | git add xx.xx 149 | git commit --amend 150 | 151 | 例子 : 152 | 153 | git add index.html 154 | 155 | git commit -m '修改html' 156 | 157 | git add index.html 158 | 159 | git commit --amend 160 | 161 | 这样两次修改的 commit 注释都是 '修改 html' 162 | 163 | ## git push (将本地版本库的文件提交到远端版本库) 164 | 165 | 语法 : 166 | 167 | git push 168 | 169 | 例子 : 170 | 171 | git push 172 | 173 | ## git checkout -b 174 | 175 | 创建分支并切换分支 176 | 177 | 178 | ## git pull (拉取远端仓库的更新) 179 | 180 | 语法 : 181 | 182 | git pull 183 | 184 | 例子 : 185 | 186 | git pull 187 | 188 | ## git stash 189 | 190 | 暂存修改 191 | 192 | ## git stash pop 193 | 194 | 释放暂存 195 | 196 | ## git stash push -m 'your messages' 197 | 推荐使用 git stash push -m 'your messages' 暂存信息 198 | ```bash 199 | git stash push -m '暂存某某功能' 200 | ``` 201 | ## git stash list 202 | 查看现有缓存代码 203 | ```bash 204 | git stash list 205 | ``` 206 | 207 | ## git stash apply @stash{index} 208 | 恢复指定的第3条记录 209 | ```bash 210 | git stash apply @stash{2} 211 | ``` 212 | 213 | ## git stash clear 214 | 清除所有缓存代码 215 | ```bash 216 | git stash clear 217 | ``` 218 | 219 | ## git checkout fileMatch (抛弃更改内容) 220 | 221 | 语法 : 222 | 223 | git checkout fileMatch 224 | 225 | 例子: 226 | 227 | ```bash 228 | git checkout . #(抛弃所有更改) 229 | 230 | git checkout index.html #(抛弃对 index.html的更改) 231 | ``` 232 | 233 | ## git reset HEAD (撤销 git add XXX) 234 | 235 | 当你把 node_modules 误加到暂存区的时候 可以使用 git reset HEAD 撤销 236 | 237 | ## git reset commit_id (撤销 git commit -m XXX) 238 | 239 | 当你 发生一个错误的 git commit 的时候想要撤销可以用 git reset commit_id (其中commit\_id可以通过 git log 查看) 240 | 241 | ## git remote rm origin (删除远端仓库) 242 | 243 | 语法: 244 | 245 | git remote rm origin 246 | 247 | ## git tag [version] 248 | 249 | 给完成好预功能的代码打上 tag 标签以标注当前版本号。 250 | 251 | 举例: 252 | ```bash 253 | git tag 1.0.0 254 | ``` 255 | 256 | ## git tag 257 | 258 | 展示所有 release 版本 259 | 260 | ## git push --tags 261 | 262 | 将所有本地 release 版本 push 到远端。 263 | 264 | ## git rm -r --cashed 265 | 266 | 删除指定缓存文件 267 | 268 | 269 | 举例删除 node_modules 270 | ```bash 271 | git rm -r --cached **/node_modules 272 | ``` 273 | 274 | ## 特别注意:git 和 github 的区别 275 | 276 | Git 是一个工具 它可以搭建github这样的全球性的仓库 也可以搭建公司内网的仓库 277 | 278 | Github 就是用git 搭建的全球性的开源版本库 279 | 280 | 281 | ## 配置你的用户名和email 282 | 283 | git config --global user.name "Your Name" 284 | 285 | git config --global user.email you@example.com 286 | 287 | 288 | #### 其他知识点 289 | 290 | git push 和 git push origin 的区别 291 | 292 | 293 | git push origin 294 | 295 | 上面命令表示,将当前分支推送到origin主机的对应分支。 296 | 如果当前分支只有一个追踪分支,那么主机名都可以省略。 297 | 298 | 299 | git push 300 | 301 | 如果当前分支与多个主机存在追踪关系,那么这个时候 -u选项会 指定一个默认主机,这样后面就可以不加任何参数使用 302 | 303 | git push。 304 | 305 | 306 | git push -u origin master 307 | 308 | 上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。 309 | 不带任何参数的git push,默认只推送当前分支,这叫做simple方式。此外,还有一种matching方式,会推送所有有对应的远程分支的本地分支。Git 2.0版本之前,默认采用matching方法,现在改为默认采用simple方式。 310 | 311 | #### 重新登录命令 312 | 313 | ```bash 314 | git config --system --unset credential.helper 315 | ``` 316 | 317 | #### http/https 记住密码命令 318 | ```bash 319 | git config --global credential.helper store 320 | ``` 321 | 322 | #### 关联远端仓库 323 | 324 | ```bash 325 | git remote add [shortname] [url] 326 | ``` 327 | 328 | 举例 329 | ```bash 330 | git remote add origin git@github.com:xxx 331 | ``` 332 | -------------------------------------------------------------------------------- /1-git/2.合作开发及其冲突.md: -------------------------------------------------------------------------------- 1 | # 多人合作开发 2 | 3 | ## 新建分支 4 | 5 | ### git branch 6 | 7 | 语法 : 8 | git branch branchName 9 | 10 | 例子 : 11 | git branch shanshan 12 | 13 | ## 查看分支 / 查看远端分支 14 | 15 | ### git branch / git branch -a 16 | 17 | 语法 : 18 | git branch / git branch -a 19 | 20 | 例子 : 21 | git branch / git branch -a 22 | 23 | 24 | ## 切换分支 25 | 26 | ### git checkout 27 | 28 | 语法 : 29 | git checkout branchName 30 | 31 | 例子 : 32 | git checkout shanshan 33 | 34 | ## 创建并切换分支 35 | 36 | ### git chekout -b 37 | 38 | 语法 : 39 | git checkout -b branchName 40 | 41 | 例子 : 42 | git checkout -b shanshan 43 | 44 | ## 同步分支 45 | 46 | ### git fetch 47 | 48 | 语法 : 49 | git fetch origin branchName 50 | 51 | 例子 : 52 | git fetch origin ds/feature1 53 | 54 | 55 | ## 创建并切换分支并且同步另一个远端分支 56 | 57 | ### git checkout -b branchA origin/branchB 58 | 59 | 语法 : 60 | git checkout -b branchA origin/branchB 61 | 62 | 例子 : 63 | git checkout -b ds/feature1 origin/ds/feature1 64 | 65 | 66 | ## 发布分支 67 | 68 | ### git push origin (将本地分支发布到远端) 69 | 70 | 语法 : 71 | git push origin branchName 72 | 73 | 例子 : 74 | git push origin shanshan 75 | 76 | ### git push origin branchA:branchB (将分支branchA发布到远端新的分支branchB) 77 | 78 | 语法 : 79 | git push origin branchName:newBranch 80 | 81 | 例子 : 82 | git push origin shanshan:dev 83 | 84 | ## 拉取远端分支 85 | 86 | 语法 : 87 | git pull origin branchName 88 | 89 | 例子 : 90 | git pull origin shanshan 91 | 92 | ## 删除本地分支 93 | 94 | ### git branch -d/-D (大写是强制删除) 95 | 96 | 语法 : 97 | git branch -d branchName 98 | 99 | 例子 : 100 | git branch -d shanshan 101 | 102 | ## 删除远端分支 103 | 104 | ### git push origin : 105 | 106 | 语法 : 107 | git push origin :branchName 108 | 109 | 例子 : 110 | git push origin :shanshan 111 | 112 | ## 合并分支 113 | 114 | ### git merge 115 | 116 | 语法 : 117 | git merge branchName 118 | 119 | 例子 : 120 | git merge shanshan (need git checkout master) 121 | 122 | ### git cherry-pick 123 | 124 | 语法 : 125 | git cherry-pick commitId 126 | 127 | 例子 : 128 | 129 | 假设你在 dev01 分支开发了2个新功能(A,B),对应2个 commitA, commitB, 但是上线前被告知只能上线功能 A,此时可以: 130 | 131 | git cherry-pick f1c1e03d 132 | 133 | f1c1e03d 是 dev01 上 commitA 的 commitId 134 | ## 终止合并 135 | 136 | 在 git merge 的过程中,我们可能遇到冲突,需要手动合并,在这期间如果出现了无法合并的情况我们就需要用到终止合并了。 137 | 138 | ```bash 139 | git merge --abort 140 | ``` 141 | 142 | 这行命令可以帮助我们终止正在进行的合并。 143 | ### git merge --abort 144 | 语法: 145 | git merge --abort 146 | 例子: 147 | git merge --abort 148 | 149 | ## 删除本地存在但远端不存在的分支 150 | 151 | ### git remote prune origin 152 | 153 | 语法 : 154 | git remote prune origin 155 | 156 | 例子 : 157 | git remote prune origin 158 | 159 | 160 | # 冲突的解决 161 | 162 | ## push失败 163 | 164 | 1.可能是 165 | 本地仓库不是最新的需要pull一下去拉取远端的更新 166 | 167 | 2.还可能是 168 | 169 | 你和你的同事修改了同一个文件夹的同一行代码 机器不知道 选择谁的保存下来需要人工合并。 170 | 171 | git pull 然后找到起冲突的文件修改合并 172 | 173 | git add . 174 | 175 | git commit -m "合并" 176 | 177 | git push 178 | 179 | # 不使用分支的多人合作 180 | 181 | 利用master 进行多人合作开发 也是可以的 182 | 分别新建或者修改不同的文件或者文件夹来进行多人合作开发 183 | 流程是 184 | git add . 185 | git commit -m '' 186 | git push ------如果失败先pull 一下 187 | 188 | :wq 是保存并退出的意思(在输入:的时候记得要用英文 不然没有效果) 189 | 190 | # git 的三个区 191 | 192 | 工作区 193 | 暂存区 194 | 版本库(本地版本库 远端版本库) 195 | 196 | ·新建一个文件默认就是在工作区 197 | 198 | ·通过git add 命令 将文件添加到暂存区 199 | 200 | 例子: git add index.html 201 | 202 | ·通过git commit -m "" 命令将文件添加到本地版本库 203 | 204 | 例子: git commit -m "我新建了一个主页" 205 | 206 | ·通过git push 命令将文件上传到远端仓库也就是远端版本库 207 | 208 | 例子: git push 209 | 210 | 注意: 211 | 如果你的文件特别多 不需要一个一个的 git add 212 | 可以通过 git add . 来一次性添加 . 就是匹配所有的意思 213 | -------------------------------------------------------------------------------- /1-git/3.版本回滚.md: -------------------------------------------------------------------------------- 1 | # 版本回滚 2 | 3 | ## 如何查看版本号 4 | 5 | git log 6 | 7 | ## 版本号乱码解决方法 8 | 9 | git config --global i18n.commitencoding utf-8 10 | 11 | git config --global i18n.logoutputencoding utf-8 12 | 13 | export LESSCHARSET=utf-8 14 | 15 | ## 如何回滚版本 16 | 17 | git reset yourHEADNAME 18 | 19 | git reset 可选的参数有 –soft –mixed –hard 20 | 21 | git reset –mixed 是默认参数 意思是仅仅将源码回滚。可以自行比较变更。 并没有回滚commit 22 | 23 | git reset --soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可 24 | 25 | git reset --hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,此命令 慎用! 26 | 27 | 28 | ## 如何回到回滚前的状态 29 | 30 | git reflog 31 | 32 | 可以查看历史提交包括已经删除的commitid。 33 | 34 | 35 | 推荐一篇有趣的文章 [前端时光机](https://juejin.im/post/5cbd82165188250a926108bd) 36 | 37 | ## 怎样删除远程仓库的某次错误提交? 38 | 39 | 假如你只是想修改上次提交的代码,做一次更完美的commit,可以这 40 | 41 | (1)git reset commitId,(注:不要带--hard)到上个版本 42 | 43 | (2)git stash,暂存修改 44 | 45 | (3)git push --force, 强制push,远程的最新的一次commit被删除 46 | 47 | (4)git stash pop,释放暂存的修改,开始修改代码 48 | 49 | (5)git add . -> git commit -m "massage" -> git push -------------------------------------------------------------------------------- /1-git/4.理解CRLF,LF以及git对它的标准化设置.md: -------------------------------------------------------------------------------- 1 | # 理解 CRLF,LF 2 | 3 | ## 是什么 4 | 5 | CRLF, LF 是用来表示文本换行的方式。 6 | 7 | ## 区别 8 | 9 | CR(Carriage Return) 代表回车,对应字符 '\r'; 10 | 11 | LF(Line Feed) 代表换行,对应字符 '\n'。 12 | 13 | Windows 系统使用的是 CRLF, 14 | 15 | Unix系统(包括Linux, MacOS近些年的版本) 使用的是LF。 16 | 17 | 18 | ## 造成的问题 19 | 20 | ```java 21 | strings.Trim(string(data), " \n") 22 | ``` 23 | 以上代码在 Ubuntu 系统上跑正常。 24 | 25 | 在Windows系统,编译之后不正常。 26 | 27 | 在Windows系统上换行符是CRLF, \r\n 28 | 29 | 只删除\n是不够的。 30 | 31 | 所以在读取文件的时候一定要小心跨平台。 32 | 33 | ## 解决方案 34 | 35 | __标准化__ 指在提交代码到git数据库(本地库) 中将文本文件中的换行符CRLF转为LF的过程 36 | 37 | __转换__ 指在检出Git数据库代码过程中将文本文件中的换行符LF转换为CRLF的过程 38 | 39 | 40 | Git 提供了一个名为 core.autocrlf 的配置,可以自动完成标准化与转换。它的设置方式如下: 41 | 42 | ```bash 43 | git config --global core.autocrlf [true | input | false] # 全局设置 44 | git config --local core.autocrlf [true | input | false] # 针对本项目设置 45 | ``` 46 | 47 | __true__ 自动完成标准化与转换 48 | __input__ 只做标准化操作,不做转换操作 49 | __false__ 提交与检出的代码都保持文件原有的换行符不变 50 | 51 | 52 | 使用 Windows 系统的开发者设置: 53 | 54 | ```bash 55 | git config --global core.aurocrlf true 56 | ``` 57 | 58 | 使用 Linux/MacOS 的开发者设置: 59 | 60 | ```bash 61 | git config --global core.autocrlf input 62 | ``` 63 | 64 | 65 | 66 | 简书原文链接: https://www.jianshu.com/p/ec9564fe1c2b (侵删) 67 | 68 | 69 | -------------------------------------------------------------------------------- /1-git/5.git 常见问题.md: -------------------------------------------------------------------------------- 1 | # 1 2 | 3 | remote: Counting objects: 104, done. 4 | error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054 5 | fatal: The remote end hung up unexpectedly 6 | fatal: early EOF 7 | fatal: index-pack failed 8 | 9 | ## 解决方法 10 | 11 | ```bash 12 | git config --global http.postBuffer 114288000 13 | ``` -------------------------------------------------------------------------------- /1-git/6.如何遴选单个文件.md: -------------------------------------------------------------------------------- 1 | ### 问题的由来 2 | 3 | 由于对新工作的不熟悉,以及老同事由于种种原因没有来得及和你介绍项目分支结构, 4 | 5 | 最主要的原因是对项目和 git 不熟悉。 6 | 7 | 不知道 git 的一些基本常识,下面我们来普及一下。 8 | 9 | ### 基本知识 10 | 11 | 大公司合作开发一般至少有3条分支(环境,不是分支) 12 | 13 | 1 master 真实生产环境代码 14 | 15 | 2 dev 待发布环境 16 | 17 | 3 feature 测试环境 18 | 19 | #### 开发规范 20 | 21 | 如果你要开发一个新功能 22 | 23 | 一般是从最稳定的 master 拉取分支,因为这里的代码最纯粹都是要用到的代码,没有其他没有用的代码。 24 | 25 | dev 是待发布的代码一般已经经过了内部测试,但是还未经过实际检验,所以不建议从dev拉取。 26 | 27 | feature 则是有很多刚开发完的功能等待测试来检验或者正在检验,一般含有很多bug,极不成熟,如果从这里拉取了代码,那将是毁性的。 28 | 29 | #### 不管怎么样这篇教程就是写 当你拉取了,测试环境的代码并开发了一个月,到了产品要发布的时候,你遇到的尴尬问题-如何避免其他人的代码污染 30 | 31 | 我只介绍没有多人同时修改同一个文件的情况,如果你修改的文件同时还有其他人修改,那就不需要看这篇文章了。 32 | 33 | 假设你修改的项目有 100 个文件再一次 commit 中有 30 个文件被修改了,其中你修改了 10 个。 34 | 35 | 我们怎么才能避免那 20 个不是你修改的文件合并到 dev 或者 master 而精确地让你修改的那 10 个文件能够被合并呢,很简单: 36 | ```bash 37 | ## 1. 38 | git checkout dev 39 | ## (或者 git checkout master) 40 | 41 | ## 2. 42 | git merge yourDirtyedBranch 43 | ## 或者 44 | git cherry-pick commitid 45 | ## 或者 46 | git merge commitid 47 | 48 | ## (把你被污染的分支合并到 dev 或者 master) 这不就污染了吗? 别急接下来的操作用是重点 49 | 50 | ## 3. 51 | git reset 52 | ## (抛弃掉这次合并但不抛弃代码) 你会看到有很多的 文件被修改了(modified),只是他们没有没添加到 暂存区 53 | 54 | ## 4. 55 | git add file1.xx 56 | 57 | git add file2.xx 58 | 59 | ## 一直到 file10.xx 把你的文件挨个添加到暂存区 60 | 61 | ## 5. 62 | git checkout . 63 | ## 抛弃掉其他你不需要修改的文件 64 | 65 | ## 6. 66 | git commit -m '上线xx功能' 67 | 68 | ## 7. 69 | git push 70 | 71 | ## 完美地去掉了被污染的文件。 72 | ``` 73 | -------------------------------------------------------------------------------- /1-git/7.如何回滚远端仓库.md: -------------------------------------------------------------------------------- 1 | ## 如何将远端仓库的某些新的commit记录删除从而使之回到一个稳定的版本 2 | 3 | 1 将本地版本回滚到某个稳定的历史版本 4 | 2 强制推送至远端 5 | ```bash 6 | # 查看历史版本 7 | git log 8 | # 记录你要回滚的commitId 9 | 10 | # 回滚 11 | git reset --hard commitId 12 | 13 | # 强推 14 | git push -f 15 | ``` 16 | 17 | (完) -------------------------------------------------------------------------------- /1-git/8.如何搭建git服务端.md: -------------------------------------------------------------------------------- 1 | # Git 服务器搭建 2 | 3 | 搭建 git 服务端需要拥有一台私人服务器,最好还有一个域名。 4 | 5 | 如果没有域名也不要紧用 ip 地址代替即可。 6 | 7 | ## step1 在服务端下载 git 8 | 9 | 以 CentOS 为例 10 | 11 | ```bash 12 | # 远程链接服服务器 用账号密码登录 或者用 ssh 免密登陆 13 | yum install git 14 | ``` 15 | 16 | 使用 yum install git 命令安装 git 17 | 18 | 没有 yum 的朋友需要自行安装 yum 19 | 20 | [如何免密登录服务器](https://github.com/PsChina/utility/blob/master/Mac/%E5%A6%82%E4%BD%95%E5%85%8D%E5%AF%86%E7%99%BB%E9%99%86%E6%9C%8D%E5%8A%A1%E5%99%A8.md) 21 | 22 | 接下来我们 创建一个git用户组和用户,用来运行git服务: 23 | 24 | ```bash 25 | groupadd git 26 | useradd git -g git 27 | ``` 28 | 29 | ## step2 创建证书登录 30 | 31 | 收集所有需要登录的用户的公钥,公钥位于id_rsa.pub文件中,把我们的公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。 32 | 33 | 如果没有该文件那么需要在本地的个人电脑上创建它(不是在服务器上创建): 34 | 35 | [创建ssh公钥私钥](https://github.com/PsChina/angularJS/blob/master/1-git/1.git%E7%9A%84%E9%85%8D%E7%BD%AE%E5%92%8C%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4.md#2%E8%BF%9E%E6%8E%A5github) 36 | 37 | ```bash 38 | cd ../ 39 | cd ../ 40 | cd ../ 41 | cd /home/git/ 42 | mkdir .ssh 43 | touch .ssh/authorized_keys 44 | cd .ssh 45 | vi authorized_keys 46 | ``` 47 | 48 | __注意:必须在服务器/home/git/目录下新建.ssh和服务端仓库目录要不然无效__。 49 | 50 | 把我们的公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。 51 | 52 | 按 o 键进入编辑模式 53 | 54 | 编辑完毕后 55 | 56 | 按 esc 57 | 58 | :wq 回车 保存并退出 59 | 60 | ## step3 61 | 62 | 初始化仓库 63 | 64 | ```bash 65 | cd ../ 66 | cd ../ 67 | cd ../ 68 | cd /home 69 | mikdir gitrepo # 创建存放远端仓库的文件夹 70 | cd /gitrepo # 进入文件夹 71 | git init --bare project.git # 创建一个裸仓库 72 | ``` 73 | 74 | 然后,把仓库所属用户改为git: 75 | 76 | ```bash 77 | chown -R git:git project.git 78 | ``` 79 | 80 | ## 克隆仓库 81 | 82 | 在含有服务端 authorized_keys 公钥的本地机器操作 83 | 84 | ```bash 85 | git clone git@47.107.154.169:/home/gitrepo/project.git 86 | # 因为我的ip绑定了域名所以我的是下面的写法 87 | # git clone git@pschina.work:/home/gitrepo/project.git 88 | ``` 89 | 90 | 然后机器上会出现 你克隆了一个空仓库的提示 91 | 92 | ```bash 93 | warning: You appear to have cloned an empty repository. 94 | ``` 95 | 96 | 接下来的 操作就简单了 97 | 98 | ```bash 99 | git add . 100 | git commit -m 'xxx' 101 | git push 102 | # 等等 103 | ``` 104 | 105 | (完) -------------------------------------------------------------------------------- /1-git/9.如何抛弃本地最新未提交的commit.md: -------------------------------------------------------------------------------- 1 | # 如何抛弃本地最新未提交的commit 2 | 3 | ```bash 4 | git reset --hard HEAD^ 5 | ``` 6 | 7 | 注意: 以上这行命令 将使得本地仓库与远端仓库保持一致,如果你有未push的本地commit将会丢失。 8 | 9 | (完) -------------------------------------------------------------------------------- /1-git/A.如何合并单个文件.md: -------------------------------------------------------------------------------- 1 | # 如何合并单个文件 2 | 3 | 假设你有两个分支它们分别是 A 和 B。 4 | 5 | 你在分支 A 上开发的某个文件(file.js)分支 B 也要用到 但是你不想把 A 上的所有更改都合并到 B 上去,这时候可以这样做: 6 | 7 | ```bash 8 | git checkout B 9 | cd path/to/file.js 10 | git checkout A file.js 11 | ``` 12 | 13 | (完) -------------------------------------------------------------------------------- /1-git/B.commit评论写错了怎么修改?.md: -------------------------------------------------------------------------------- 1 | # commit 评论写错了怎么修改? 2 | 3 | 答: 4 | 5 | 运行如下命令: 6 | 7 | ```bash 8 | git commit --amend -m '这才是要提交的文字' 9 | ``` -------------------------------------------------------------------------------- /1-git/C.git代理.md: -------------------------------------------------------------------------------- 1 | # git代理 2 | 无论是 github 还是 gitlab 都是境外网站,常常会有网络延迟导致卡顿,当我们的远端仓库中在境外或者需要经过很多节点的时候我们可以给 git 设置代理来加速对远端仓库的访问速度。 3 | 4 | 5 | ## 设置代理 6 | 7 | http代理: 8 | ```bash 9 | git config --global http.proxy http://xxx.x.x.x:xxxx 10 | 11 | git config --global https.proxy http://xxx.x.x.x:xxxx 12 | ``` 13 | 14 | socks5代理: 15 | ```bash 16 | git config --global http.proxy 'socks5://xxx.x.x.x:xxxx' 17 | 18 | git config --global https.proxy 'socks5://xxx.x.x.x:xxxx' 19 | ``` 20 | 21 | ## 取消代理 22 | 23 | ```bash 24 | git config --global --unset http.proxy 25 | 26 | 27 | git config --global --unset https.proxy 28 | ``` 29 | 30 | ## 更改 github host 31 | 32 | ```bash 33 | vi /etc/hosts 34 | ``` 35 | 36 | 添加 `192.30.253.113 github.com` 37 | -------------------------------------------------------------------------------- /1-git/D.git子仓库.md: -------------------------------------------------------------------------------- 1 | ## 克隆含有子仓库的仓库 2 | 3 | 分为两步 4 | 5 | 1、克隆主仓库 6 | 2、克隆子仓库 7 | 8 | ### 克隆主仓库 9 | 10 | 这个就是普通的克隆一下仓库就行 通过 ssh 或者 http 链接 11 | 12 | ```bash 13 | git clone xxxxxx 14 | ``` 15 | 16 | ### 克隆子仓库 17 | 18 | 子仓库有两种方式分别是 `submodule` 和 `subtree` 这里介绍 `submodule` 这种 19 | 20 | 1、在克隆完主仓库以后我们 cd 到主仓库的根目录 21 | 22 | 2、运行命令 23 | 24 | ```bash 25 | git submodule init 26 | ``` 27 | 28 | ```bash 29 | git submodule update 30 | ``` 31 | 32 | 至此子仓库克隆完成 33 | -------------------------------------------------------------------------------- /1-git/E.如何暂存正在编辑的代码.md: -------------------------------------------------------------------------------- 1 | # 暂存代码 2 | 3 | 当我们在开发过程中,功能开发到一半如果遇到紧急任务,或者需要修复一个线上bug,需要切换分支,此时手头的任务不能立即完成,不合适commit,但是又需要切换分支,我们就可以使用git的暂存代码的功能了。 4 | 5 | ## git stash save stashMarkName 6 | 7 | git stash save stashMarkName 这个命令可以帮助我们存储当前的修改。 8 | 9 | stashMarkName 指的是此次暂存代码的备注信息 10 | 11 | 每次运行 git stash save xxxx 都会把当前未保存的代码入栈到 stash 列表里面 并生产一个索引 index stash@{index} 12 | 13 | ## git stash list 14 | 15 | 这个命令可以查看所有暂存的代码列表例如 16 | 17 | ```bash 18 | stash@{0}: On branchName: stashMarkNameA 19 | stash@{1}: On branchName: stashMarkNameB 20 | stash@{2}: On branchName: stashMarkNameC 21 | ``` 22 | ## git stash pop stash@{index} 23 | 24 | 这个命令可以让指定的暂存代码出栈 25 | 26 | 如果想要备注为 stashMarkNameB 的暂存代码出栈可以这么写 27 | 28 | ```bash 29 | git stash pop stash@{1} 30 | ``` 31 | 32 | 而如果省略 stash{index} 33 | 34 | ```bash 35 | git stash pop 36 | ``` 37 | 38 | 则会出栈最近一次的暂存代码 39 | 40 | 类似的命令还有 git stash apply 它的作用和 git stash pop 类似但是只检出并不会出栈。 41 | 42 | ## git stash drop stash@{index} 43 | 44 | 该命令用于删除某个暂存代码 45 | 46 | ## git stash clear 47 | 48 | 该命令用于删除所有暂存代码 也就是清空暂存列表了 49 | 50 | ## git stash stash{index} 51 | 52 | 该命令用于查看某一条暂存代码的差异 53 | 54 | git stash stash{index} -p 用于查看完整差异 55 | 56 | (完) 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /2-gulp/1.gulp入门.md: -------------------------------------------------------------------------------- 1 | ## 1.gulp 是什么 2 | 3 | gulp 是一个 自动化构建工具。 4 | gulp 是基于nodejs的。 5 | 6 | ## 2.他都能干啥 7 | 8 | ·启动服务。 9 | ·编译less/sass。 10 | ·合并文件(css js html 普通文件)。 11 | ·压缩文件(css js html 普通文件 图片)。 12 | ·打包文件。 13 | ·重命名。 14 | 15 | ·mock数据。 (就是后端开发跟不上前端开发的速度的时候 前端可以用mock来自己写后端接口) 16 | ·检测文件变化。 (当我编辑了某个文件 gulp 能够检测到这种更改并且你可以在这时做你想做的事) 17 | ·热替换。 (文件变化后浏览器自动刷新) 18 | ·为文件添加md5 后缀。 19 | 20 | ## 3.如何开始呢 21 | 22 | · npm install gulp -g 23 | · 新建一个入口文件 gulpfile.js。 24 | · 在gulpfile.js里面写代码。 25 | · 引入gulp 定义默认任务。 (default 任务必须实现 不然会报错) default是所有任务的入口。 26 | · 在当前文件夹右击鼠标打开git 或者 shift+右键在当前文件夹打开cmd 输入 gulp 回车 即可运行 27 | 28 | ## 4.介绍api(application programming interface) 29 | 30 | ### task 31 | 32 | task 他是一个 function 他接收 至少2个参数。 33 | 第一个参数 是一个字符串 他用来形容这个任务的性质或者功能 也就是这个任务的名字。 34 | 第二个参数 是一个function 或者 是一个数组。 35 | 如果他是一个function 那么他会在这个任务被调用的时候 执行。 36 | 如果他是一个数组 那么 gulp 会去遍历这个数组 拿到这个数组里面的所有任务 依次执行。 37 | 38 | 用法: 39 | 40 | gulp.task('taskOne',function(){}) 41 | gulp.task('default',['taskOne']) 42 | 43 | ### src 44 | 45 | src也是一个function。 46 | 他接收 一个 参数。 47 | 这个参数可以是 字符串 也可以是一个 数组 你也可以给他一个 正则表达式 。 48 | 49 | 他是一个获取文件的函数。 src 的意思是source 来源。 50 | 51 | 用法: 52 | 53 | gulp.src('./index.html') 54 | 55 | ### pipe 56 | 57 | pipe也是一个function。 58 | 他接收一个参数。 59 | 这个参数是一个函数的调用。 60 | 61 | pipe是gulp的 向流水线一样的环节 叫做管道流。 62 | pipe 这个函数会把上一级的输出当作是这一级的输入。 63 | 而这一级的输出会被当作下一级的输入。 64 | 65 | 用法: 66 | 67 | gulp.pipe((function(){})()) 68 | 69 | ### dest 70 | 71 | dest 也是一个function。 72 | 他接受一个参数。 73 | 这个参数是一个字符串。 74 | 用这个字符串来形容你要输出的路径。 75 | 76 | 把文件输出到指定的目录。 77 | 78 | 用法: 79 | 80 | gulp.dest('./') 81 | 82 | ## 5功能的介绍 83 | 84 | ### ·拷贝文件(自带的) 85 | ```javascript 86 | gulp.task('copy',function(){ 87 | gulp.src('./index.html') 88 | .pipe(gulp.dest('./html/')) 89 | }) 90 | ``` 91 | 把 与gulpfile.js 同级目录的 index.html 拷贝到 ./html/ 目录下。 92 | 93 | ### ·合并文件(gulp-concat) 94 | ```javascript 95 | var concat = require('gulp-concat') 96 | 97 | gulp.task('concatCss',function(){ 98 | gulp.src(['style1.css','style2.css']) 99 | .pipe(concat('style.css')) 100 | .pipe(gulp.dest('./css/')) 101 | }) 102 | ``` 103 | 将 style1.css 与 style2.css 合并 成 style.css 并输出到 ./css/ 目录下。 104 | 105 | ### ·压缩css(gulp-clean-css) 106 | ```javascript 107 | var mincss = require('gulp-clean-css') 108 | 109 | gulp.task('minCss',function(){ 110 | gulp.src('style.css') 111 | .pipe(mincss()) 112 | .pipe(gulp.dest('./css/')) 113 | }) 114 | ``` 115 | 将 style.css 压缩 并输出到 ./css/ 目录下 116 | 117 | ### ·重命名文件(gulp-rename) 118 | ```javascript 119 | var rename = require('gulp-rename'); 120 | 121 | gulp.task('rename',function(){ 122 | gulp.src('style.css') 123 | .pipe(rename('style.min.css')) 124 | .pipe(gulp.dest('./yourproject/css/')) 125 | }) 126 | ``` 127 | 把 style.css 重命名为 style.min.css 并输出到 ./yourproject/css/ 目录下。 128 | 129 | ### ·压缩图片(gulp-imagemin) 130 | ```javascript 131 | var minimg = require('gulp-imagemin') 132 | 133 | gulp.task('minImage',function(){ 134 | gulp.src('./image.png') 135 | .pipe(minimg()) 136 | .pipe(gulp.dest('./image/')) 137 | }) 138 | ``` 139 | 将 image.png 压缩并输出到 ./image/ 目录下 (不仅仅支持.png)。 140 | 141 | ### ·压缩html(gulp-htmlmin) 142 | ```javascript 143 | var htmlmin = require(gulp-htmlmin) 144 | 145 | var options = { 146 | removeComments: true,//清除HTML注释 147 | collapseWhitespace: true,//压缩HTML 148 | collapseBooleanAttributes: true,//省略布尔属性的值 ==> 149 | removeEmptyAttributes: true,//删除所有空格作属性值 ==> 150 | removeScriptTypeAttributes: true,//删除 7 | 8 | ### entry.js 9 | ```javascript 10 | var module1 = require('./module1.js'); 11 | 12 | var module2 = require('./module2.js'); 13 | ``` 14 | ### module1.js 15 | ```javascript 16 | console.log('我是模块一'); 17 | ``` 18 | ### module2.js 19 | ```javascript 20 | console.log('我是模块二'); 21 | ``` 22 | ### gulpfile.js 23 | ```javascript 24 | var gulp = require('gulp') 25 | 26 | var browserify = require('browserify') /*注意他不是以 gulp- 开头的包 说明他是一个node 的包 需要将node的流转成gulp的流*/ 27 | 28 | // browserify 是获取入口文件的 29 | 30 | var source = require('vinyl-source-stream'); //合并js 的 31 | 32 | var buffer = require('vinyl-buffer'); // 把node 的流转为 gulp的流的 33 | 34 | var connect = require('gulp-connect') // 启动前端服务的 35 | 36 | var rev = require('gulp-rev') //生成md5后缀的 37 | 38 | var collector = require('gulp-rev-collector'); //自动替换 39 | 40 | var watch = require('gulp-watch'); //检测文件变化的 41 | 42 | gulp.task('module',function(callback){ // 定义模块化任务 43 | 44 | browserify({ //获取入口 文件 45 | entries:['./entry.js'] 46 | }).bundle() //进行打包工作 47 | .pipe(source('bundle.js')) //进行合并工作 给合并好的文件取一个名字 48 | .pipe(buffer()) //将node流转为gulp流以便将文件流交给gulp的包以后能正常工作 49 | .pipe(rev()) //生成md5后缀 50 | .pipe(gulp.dest('./')) //将有md5后缀的bundle.js文件输出到同级目录 51 | .pipe(rev.manifest()) //生成对应关系 52 | .pipe(gulp.dest('./')) //将记录对应关系的json 输出到同级目录 53 | .on('end',callback) 54 | 55 | }) 56 | 57 | gulp.task('reloadSrc',['module'],function(){ //定义自动替换src的任务 58 | // ['module'] 是为了将reloadSrc 这个任务 当作一个回调函数注入module任务中 达到异步转同步的效果。 59 | gulp.src(['./index.html','rev-manifest.json']) /*拿到主页 和 含有对应关系的json文件*/ 60 | .pipe(collector({ //调用自动替换的包 61 | replaceReved:true //开启自动替换 62 | })) 63 | .pipe(gulp.dest('./'))//将替换好src 的主页输出到同级目录(httpServer根目录) 64 | }) 65 | 66 | gulp.task('reloadPage',function(){ //定义自动刷新浏览器的任务 67 | gulp.src('.') 68 | .pipe(connect.reload()) 69 | }) 70 | 71 | gulp.task('watch',function(){ //定义监听任务 72 | gulp.watch(['./module1.js','./module2.js'],['module','reloadSrc']) /*当任意子模块有变化将重新运行模块化任务 和 替换src 的任务*/ 73 | gulp.watch('./index.html',['reloadPage']) // 主页有更新将重新刷新浏览器 74 | }) 75 | 76 | gulp.task('httpServer',function(){ //启动前端服务器i 77 | connect.server({ 78 | port:8000, //端口号为8000 79 | livereload:true //打开自动刷新 80 | }) 81 | }) 82 | 83 | 84 | gulp.task('default',['httpServer','module','watch']) /*依次启动 前端服务器 模块化任务 和 监听任务*/ 85 | ``` -------------------------------------------------------------------------------- /2-gulp/4.css自动添加前缀.md: -------------------------------------------------------------------------------- 1 | # postcss 2 | 3 | 简介: 我们在开发的过程中 避免不了写css兼容 为何不用机器来做呢? 4 | 5 | let's go! 6 | 7 | ## 基于gulp 8 | 9 | ```js 10 | var gulp = require('gulp'); 11 | 12 | gulp.task('autoprefixer', function () { 13 | var postcss = require('gulp-postcss'); // css处理平台 14 | var autoprefixer = require('autoprefixer'); // 自动添加前缀 15 | 16 | gulp.src('./*.css') //拿到同级目录下所有的css 17 | .pipe(postcss([ autoprefixer({ browsers: ['last 2 versions'] }) ])) //执行加前缀的任务 18 | .pipe(gulp.dest('./dist/postcss')); //输出到./dist/postcss 文件夹下 19 | }); 20 | 21 | gulp.task('default',['autoprefixer']) //默认任务 22 | ``` 23 | -------------------------------------------------------------------------------- /2-gulp/5.gulp异步任务转同步.md: -------------------------------------------------------------------------------- 1 | ## gulp-sequence 2 | gulp-sequence 是一个异步转同步的包 可以让gulp 的异步任务 阻塞同步执行 3 | 4 | 1.给每个任务加上 return 关键字。 5 | 2.调用方法时,将方法名作为参数放在 __sequence__ 内使用。 6 | ```js 7 | var gulp = require('gulp'); 8 | 9 | var sequence = require('gulp-sequence'); //异步转同步的包 10 | 11 | gulp.task('copyFile1',function(){ 12 | return gulp.src('file1.txt') 13 | .pipe(gulp.dest('./dist/')) 14 | }) 15 | 16 | gulp.task('copyFile2',function(){ 17 | return gulp.src('file2.txt') 18 | .pipe(gulp.dest('./dist/')) 19 | }) 20 | 21 | gulp.task('default',function(){ 22 | return sequence('copyFile1','copyFile2',function(){ 23 | console.log('任务完成') 24 | }) 25 | }) 26 | ``` -------------------------------------------------------------------------------- /2-gulp/demo/dataBase.json: -------------------------------------------------------------------------------- 1 | {"users":[{"user":"1","password":"2"},{"user":"zhangsan","password":"123456"},{"user":"123","password":"234"}]} -------------------------------------------------------------------------------- /2-gulp/demo/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var webserver = require('gulp-webserver'); 3 | var qs = require('qs') 4 | var url = require('url'); 5 | 6 | var fs = require('fs'); 7 | 8 | var buffer = fs.readFileSync('./dataBase.json'); 9 | 10 | var dataBase = {}; 11 | 12 | if(buffer.length){ 13 | dataBase=JSON.parse(buffer.toString()); 14 | }else{ 15 | dataBase = { 16 | users:[] 17 | } 18 | } 19 | 20 | gulp.task('mockServer', function () { 21 | gulp.src('.') 22 | .pipe(webserver({ 23 | port: 3000, 24 | middleware: function (req, res, next) { 25 | res.setHeader('Access-Control-Allow-Origin', '*'); 26 | var method = req.method, 27 | urlObj = url.parse(req.url), 28 | pathname = urlObj.pathname; 29 | 30 | if (method == 'POST') { 31 | var postDataStr = ''; 32 | req.on('data', function (chunk) { 33 | postDataStr += chunk; 34 | }) 35 | 36 | req.on('end', function () { 37 | 38 | //1 JSON 39 | //2 qs 40 | var postDataJson; 41 | 42 | if (postDataStr.indexOf('{') !== -1 && postDataStr.indexOf('}') !== -1) {//判断是否是json数据还是表单数据 43 | postDataJson = JSON.parse(postDataStr) //处理json str 44 | } else { 45 | postDataJson = qs.parse(postDataStr) //处理表单 str 46 | } 47 | //得到一个对象 那么就方便了 48 | 49 | switch(pathname){ 50 | case '/register': 51 | console.log(dataBase) 52 | var users = dataBase['users']; 53 | res.setHeader('content-type','application/json;charset=utf-8') 54 | var exist = false; 55 | var newUser = { 56 | user: postDataJson.user, 57 | password:postDataJson.password 58 | } 59 | for( var i = 0, length = users.length; i < length; i++ ){ 60 | if(users[i].user === postDataJson.user){ 61 | exist = true; 62 | break; 63 | } 64 | } 65 | 66 | if(!exist){ 67 | users.push(newUser); 68 | var ok = fs.writeFileSync('./dataBase.json',JSON.stringify(dataBase)); 69 | if(!ok){ 70 | res.write('{"status":"1"}') // 1代表 注册成功 71 | }else{ 72 | res.write('{"status":"0"}') // 0代表 服务器内部错误 注册失败 73 | } 74 | }else{ 75 | res.write('{"status":"-1"}') // -1代表用户存在 76 | } 77 | 78 | 79 | res.end(); 80 | break; 81 | case '/detectionUser': 82 | 83 | var users = dataBase['users']; 84 | var exist = 0; 85 | if(users){ 86 | for(var i = 0,length=users.length; i 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
用户存在
12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /2-gulp/demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "dependencies": { 4 | "gulp":"^3.9.1", 5 | "gulp-webserver":"^0.9.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /3-angularJS-part1/1.angularJS-指令以及$scope的介绍.md: -------------------------------------------------------------------------------- 1 | # angularJS 2 | 3 | 介绍: 他是一个对象 类似jQuery 有 jQuery 和 $, angularJS 有 angular这个对象。 4 | 5 | ## $scope 6 | 7 | ng-app 管理的是 $rootScope 起作用的区域 8 | 9 | ng-controller 管理的是与自己对应的 $scope 起作用的区域 10 | 11 | ### $scope 12 | 13 | 介绍: 它是angular 里面的 model 数据模型 -> 就是数据 他是一个内置服务 可以在需要的时候注入他 14 | 15 | #### $scope.$watch 16 | 17 | 用来监听 $scope下的属性变化 18 | 19 | #### $scope.$emit 20 | 21 | 冒泡事件 22 | 23 | #### $scope.$on 24 | 25 | 监听事件 26 | 27 | #### $scope.$broadcast 28 | 29 | 广播事件 30 | 31 | #### $scope.$digest 32 | 33 | 局部脏检查 只检查更新 当前$scope 和子scope 34 | 35 | #### $scope.$apply 36 | 37 | 全局脏检查 从rootScope 开始遍历所有子scope 38 | 39 | #### $scope.$last 40 | 41 | 最后一个数据是否被更新到UI 如果是 值为true 否则为false 42 | 43 | 44 | ## 指令 45 | 46 | ### ng-app 47 | 48 | 用法: ng-app="模块名" 49 | 50 | 例子: ng-app="myApp" //名字自定义 51 | 52 | 作用: 就是规定 angular这个对象起作用的范围 也就是规定管理边界 53 | 54 | ### ng-controller 55 | 56 | 用法: ng-controller="控制器名" 57 | 58 | 例子: ng-controller="controller" 59 | 60 | 作用: 规定controller这个控制器的控制范围 61 | 62 | ### ng-model 63 | 64 | 用法: 它用于我们的input select textarea 等能输入的表单元素 ng-model='$scope下的变量' 65 | 66 | 例子: ng-model="message" ($scope.message="Hello Angular") 67 | 68 | ### ng-change 69 | 70 | 作用: 绑定 onchange 事件 在 input框 value 改变的时候触发。 71 | 72 | 用法: 必须与ng-model配合使用 73 | 74 | 例子: 75 | 76 | ```html 77 | 78 | 79 | 80 | 81 | 82 | 90 | ``` 91 | 92 | ### ng-if 93 | 94 | 介绍: 如果在一个元素上绑定 95 | ng-if="true" 那么这个元素将被渲染 96 | 97 | ng-if="false" 将不被渲染 也就是dom结构会被移除 98 | 99 | 不仅仅可以等于 布尔值 还可以等于 $scope 下的变量 100 | 101 | 例如 ng-if="message" 102 | 103 | ### ng-show 104 | 105 | 介绍: 如果在一个元素上绑定 ng-show="true" 那么这个元素将被显示 106 | 107 | ng-show="false" 这个元素将被隐藏 通过设置display: block/none 来控制 108 | 109 | ### ng-hide 110 | 111 | 介绍 ng-hide="false"显示 否则 隐藏 通过设置display: block/none 来控制 112 | 113 | ### ng-repeat 114 | 115 | 功能: 顾名思义 repeat是重复的意思 116 | 117 | 就是说 绑定这个指令的 dom元素 会被重复渲染 118 | 119 | 用法 ng-repeat="value in array" 有点像 for in 的味道 其中 array 是$scope下的变量 它必须是一个array 120 | 121 | ### ng-options 122 | 123 | 功能: 循环数组渲染 select框中的 option 124 | 125 | 用法: 126 | 127 | ```html 128 |
129 | 130 | 136 | ``` 137 | 138 | ### ng-class 139 | 140 | 功能 用来代替 class="banner"这种原生属性的 141 | 142 | 用法 ng-class="字符串或者是变量" 143 | 144 | 绑定多个类名 ng-class="[classNameA,classNameB]" 可以采用数组的方式绑定多个类名 145 | 146 | ### ng-click 147 | 148 | 功能 用来代替 onclick="fn()"这种原生属性 149 | 150 | 用法 ng-click="fn()" 151 | 152 | ### ng-style 153 | 154 | 功能 用来代替 style 这种原生属性的 155 | 156 | ng-style="{background:ok? 'green' : 'red'}" 157 | 158 | ### ng-src 159 | 160 | 功能 用来代替 src 这种原生属性的 161 | 162 | ng-src="{{path}}" 163 | 164 | ### ng-href 165 | 166 | 功能 用来代替 href 这种原生属性的 167 | 168 | 动态改变href 169 | 170 | ### ng-init 171 | 172 | 功能 用来 初始化 数据 的 173 | 174 | ng-init="a=10" 相当于$scope.a=10; 175 | 176 | ### ng-bind 177 | 178 | 功能 绑定 数据 类似 {{}} 与其区别是 {{}} 在angular生效前 网页上会显示{{data}} 而 ng-bind不会有这一种问题 179 | 180 | ng-bind="message"; 181 | 182 | ### ng-template&ng-include 183 | ```html 184 | 185 | 190 | 191 |
192 | 193 |
194 | ``` 195 | 196 | ### ng-transclude 197 | 198 | ```html 199 | 200 | 头部 201 | 脚部 202 | 203 | ``` 204 | ```js 205 | angular.module('app',[]) 206 | .directive('direc',function(){ //ng-transclude 例子 207 | return { 208 | replace:true, 209 | template:'
123
', 210 | transclude:{ 211 | title:'mytitle', 212 | footer:'myfooter' 213 | } 214 | } 215 | }) 216 | ``` 217 | 218 | ### ng-checked 219 | 220 | 用于绑定 checked 属性的指令 221 | 222 | ```js 223 | angular.module('app',[]) 224 | .controller('main',['$scope',function($scope){ 225 | $scope.value = true; 226 | }]) 227 | ``` 228 | 229 | ```html 230 | 231 | 232 | 233 | 234 | 235 | ``` 236 | 237 | 以上是部分常用指令 238 | 239 | ## demo 240 | ```html 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | {{message}} 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 272 | ``` 273 | 274 | # 官方文档 275 | 276 | https://docs.angularjs.org/api/ng -------------------------------------------------------------------------------- /3-angularJS-part1/2.angularJS-内置过滤器.md: -------------------------------------------------------------------------------- 1 | # 过滤器 2 | 它是用来格式化 或者 过滤 我们的数据的 3 | 4 | | 告诉 angularJS 你要开始过滤数据了 5 | 6 | : 告诉 angularJS 你要对过滤器传参了 7 | 8 | ## 1. currency 9 | 10 | 功能 格式化 数字 将他变为 货币格式 11 | 12 | 用法 13 | 14 | 1. 无参用法 {{1000 | currency}} 效果 $1,000.00 15 | 16 | 2. 有参用法1 {{1000 | currency :'¥'}} 效果 ¥1,000.00 (alt+0165) 17 | 18 | 3. 有参用法2 {{1000 | currency : char}} $scope.char='¥' 效果 ¥1,000.00 19 | 20 | ## 2. date 21 | 22 | 功能 格式化 时间 (时间戳) 23 | 24 | 用法 25 | 26 | 1. 无参用法 {{1504525453449 | date}} 效果 Sep 4, 2017 27 | 28 | 2. 有参用法1 {{1504525453449 | date : 'EEE-dd-ss'}} 29 | {{1504525453449 | date : 'yyyy-MM-dd hh mm ss EEEE'}} 30 | 31 | 解析 yyyy 表示获取年份 2017 yy 17 32 | 33 | MM 获取月份 34 | 35 | dd 获取天 36 | 37 | hh 获取小时 38 | 39 | mm 获取分钟 40 | 41 | ss 获取秒 42 | 43 | EEEE 获取星期 EEE Mon. 44 | 45 | 你可以自由组合他们 46 | 47 | 3. 有参用法2 {{1504525453449 | date : fromatStr}} $scope.fromatStr = 'yyyy/MM/dd' 48 | 49 | ## 3. filter 50 | 51 | 功能 筛选我们的数据 会使我们的数据变少或者不变 但是 数据的格式不变 52 | 53 | 用法 54 | 55 | $scope.array= [ 56 | {name:'kimi',age:3}, 57 | {name:'cindy',age:4}, 58 | {name:'anglar',age:4}, 59 | {name:'shitou',age:6}, 60 | {name:'tiantian',age:5} 61 | ] 62 | 63 | 1. 无参用法 {{array | filter }} 效果 全部显示 64 | 65 | 2. 有参用法1 {{array | filter :3 }} 显示含有属性 3 的对象 {{array | filter :'i' }} 显示含有i的属性的对象 66 | 67 | 有参用法2 {{array | filter :value }} $scope.value = 'i' 68 | 69 | 有参用法3 {{array | filter :fn }} $scope.fn = function(data){ return data.age>4 } 70 | 71 | ## 4. json 72 | 73 | $scope.jsonObj = {name:'zangsan',age:18} 74 | 75 | 用法 {{ jsonObj | json }} 就这一个用法 76 | 77 | 效果 将 js 对象 格式化为 json 对象 78 | 79 | ## 5. limitTo 80 | 81 | 他是用来限制 string 或者 array 这两种数据类型的 显示的长度 {{有效的那一部分}} 82 | 83 | 用法 84 | 85 | 无参用法 会全部显示 {{ 'nihao' | limitTo }} 效果 nihao 86 | 87 | string {{ 'nihao' | limitTo :2 }} 效果 ni 88 | 89 | array {{ [1,2,3,4] | limitTo :3 }} 效果 [1,2,3] 90 | 91 | tip: array 里面可以放任何东西 92 | 93 | ## 6. lowercase 94 | 95 | 功能 小写全部字母 string 96 | 97 | 用法 仅有无参 用法 {{ 'Hello World' | lowercase }} => hello world 98 | 99 | ## 7. uppercase 100 | 101 | 功能 大写全部字母 string 102 | 103 | 用法 仅有无参 用法 {{ 'Hello World' | uppercase }} => HELLO WORLD 104 | 105 | ## 8. number 106 | 107 | 无参用法 108 | 109 | {{1000 | number}} 效果 1,000 110 | 111 | 注意 默认精确到小数点后三位。 112 | 113 | 有参数用法 114 | 115 | {{1000 | number :2 }} 效果 1,000.00 116 | 117 | {{3.141592653 | number :3 }} 效果 3.142 118 | 119 | ## 9. orderBy 120 | 121 | demo 122 | ```javascript 123 | $scope.array= [ 124 | {name:'kimi',age:3}, 125 | {name:'cindy',age:4}, 126 | {name:'anglar',age:4}, 127 | {name:'shitou',age:6}, 128 | {name:'tiantian',age:5} 129 | ]; 130 | ``` 131 | ```html 132 | 133 | 134 | 135 | {{item.name}} 136 | 137 | 138 | {{item.age}} 139 | 140 | 141 | 142 | ``` 143 | 144 | 用法 1 orderBy :'-name' 这是通过 属性name里面值 来进行降序排列 145 | 146 | 2 orderBy :'age' 这是通过 属性age里面值 来进行升序排列 147 | 148 | 3 orderBy : value 这是通过 $scope下的value 属性里面值来进行排序 也就是 动态排序 149 | 150 | ## 如何通过ng-bind使用过滤器 151 | 152 | ```html 153 |
154 | ``` 155 | -------------------------------------------------------------------------------- /3-angularJS-part1/3.angularJS-自定义过滤器.md: -------------------------------------------------------------------------------- 1 | # 自定义过滤器 2 | 3 | ## api filter 4 | 5 | 怎样获取这个api 6 | ```javascript 7 | angular.module('app',[]).filter 8 | ``` 9 | 或者 10 | ```javascript 11 | var app = angular.module('app',[]) 12 | 13 | app.filter 14 | ``` 15 | ## 如何使用 16 | ```javascript 17 | var app = angular.module('app',[]) 18 | 19 | app.filter('yourFilterName',function(){ // 第一个参数是 自定义过滤器的名字 20 | // 第二个参数 是实现 该过滤器的回调函数 21 | 22 | // 注意事项 需要在回调函数里面再次return 一个 function 23 | 24 | return function(input,parma1,parma2){ //第一个参数是 你要过滤的数据 25 | //第二个及其以后的参数 都是 在外面调用的时候通过 : 传递进来的值 26 | 27 | } 28 | }) 29 | ``` 30 | ## demo1 31 | ```javascript 32 | app.filter('upperCaseLetterOfRange',function(){ // 33 | 34 | return function(input,parma1,parma2){ 35 | 36 | /*拿到 通过传经来索引截取的字符串*/ 37 | var str = input.substring(parma1,parma2*1+1); // 38 | 39 | var output = input.replace(str/*通过传经来索引截取的字符串*/,str.toUpperCase()/*通过传经来索引截取的字符串.toUpperCase()*/) 40 | 41 | return output; 42 | 43 | } 44 | }) 45 | ``` 46 | ## demo2 47 | ```javascript 48 | app.filter('lowerCaseLetterOfRange',function(){ // 49 | 50 | return function(input,parma1,parma2){ 51 | 52 | /*拿到 通过传经来索引截取的字符串*/ 53 | var str = input.substring(parma1,parma2*1+1); 54 | 55 | var output = input.replace(str/*通过传经来索引截取的字符串*/,str.toLowerCase()/*通过传经来索引截取的字符串.toLowerCase()*/) 56 | 57 | return output; 58 | 59 | } 60 | }) 61 | ``` 62 | ## demo3 63 | ```javascript 64 | app.filter('remove',['$rootScope',function($rootScope){ 65 | 66 | return function(input,parma){ 67 | 68 | var exp = new RegExp(parma,'g'); 69 | 70 | var output = input.replace(exp,'') 71 | 72 | return output; 73 | 74 | } 75 | 76 | }]) 77 | ``` 78 | ## demo4 79 | ```javascript 80 | app.filter('formatSentence',['$rootScope',function($rootScope){ 81 | 82 | return function(input){ 83 | 84 | var output = input.split(/'.'|'。'/).map(function(value,index,array){ 85 | return value.replace(value.charAt(0),value.charAt(0).toUpperCase()) 86 | }).join('') 87 | 88 | return output; 89 | 90 | } 91 | 92 | }]) 93 | ``` -------------------------------------------------------------------------------- /3-angularJS-part1/4.angularJS-内置服务.md: -------------------------------------------------------------------------------- 1 | # angular 内置服务 2 | 3 | 如果你要用到某个服务,你必须注入它。 4 | 5 | 服务是一个对象或者函数。 6 | 7 | ## 1. $scope (数据模型 就是我们存放数据的地方) 8 | 9 | 它是属于 某个控制器的 ng-controller="谁" $scope 就属于谁 10 | 11 | 如果页面中有多个 ng-controller 咋办 不用担心会一一对应的 app.controller('控制器名',function($scope){}) 12 | 13 | 它不仅仅保存了我们 数据 还保存了与这个数据相关的 dom 元素 14 | 15 | 还挂载了 修改dom 的function 16 | 17 | ## 2. $rootScope 18 | 19 | 它是属于 angularJS 的 也就是全局的 20 | 21 | 它的功能和 $scope 一样 只是作用范围 和 层级关系不一样 22 | 23 | 你可以通过 $scope.$parent 来找到 当前$scope 的上一个 $scope 如果它的上一级不是$scope就是 $rootScope 24 | 25 | ## 3. $http 26 | 27 | 他是我们angularJS 里面用来代替 $.ajax / XMLHttpRequest 的一种东西 28 | 29 | 那么 $http 与 $.ajax / XMLHttpRequest 有啥区别 为啥要代替他们呢 30 | 31 | 32 | $http 相比 $.ajax 的 data 这个字段 他不能自动将json数据 转换为 表单数据 33 | 34 | 也就是说无法完成 {name:'zhangsan',age:18} = > "name=zhangsan&age=18"; 需要手动实现 35 | 36 | 我们知道 angularJS 是通过脏检查机制来 刷新数据的也就是说 尽量的减少dom查询甚至不查询dom 37 | 38 | //-------- 39 | 40 | 我们知道 ajax技术是异步的 所以会绕开angular 的自动脏检查 41 | 42 | 所以我们需要angularJS 提供能 自动脏检查 并且 能更好的处理异常的 服务 因此诞生了 $http 43 | 44 | //------用法 45 | 1. 46 | ```javascript 47 | $http({ 48 | url:'', 49 | method:'', 50 | data:'' 51 | }) 52 | .success(function(){ 53 | 54 | }) 55 | .error(function(){ 56 | 57 | }) 58 | ``` 59 | 2. 60 | ```javascript 61 | $http({ 62 | url:'', 63 | method:'', 64 | data:'' 65 | }) 66 | .then(function(){ 67 | 68 | },function(){ 69 | 70 | }) 71 | ``` 72 | 73 | ## $timeout 74 | 75 | 他是用来代替 setTimeout 的。 76 | 77 | 为什么要代替setTimeout呢。 78 | 79 | 因为 setTimeout 是一个 异步操作 会绕开 angular 控制里面的自动脏检查机制。 80 | 81 | 那么 $timeout 就实现了 在异步操作里面自动脏检查。 82 | 83 | ### 取消$timeout 84 | ```javascript 85 | var timer = $timeout(fn,1000); 86 | 87 | $timeout.cancel(timer); 88 | ``` 89 | ### 尝试自己实现$timeout 90 | 91 | 1. 原生 92 | ```javascript 93 | function $timeout(fn,time){ 94 | return setTimeout(function(){ 95 | try{ 96 | fn(); 97 | }catch(error){ 98 | throw new Error(error); 99 | }finally{ 100 | $scope.$apply() 101 | } 102 | },time) 103 | } 104 | 105 | $timeout.cancel = function(id){ 106 | clearTimeout(id); 107 | } 108 | ``` 109 | 2. angularJS 110 | ```javascript 111 | angular.module('app',[]) 112 | .provider('timeout',function(){ 113 | return { 114 | $get:['$rootScope',function($rootScope){ 115 | 116 | function $timeout(fn,time){ 117 | return setTimeout(function(){ 118 | try{ 119 | fn(); 120 | }catch(error){ 121 | throw new Error(error); 122 | }finally{ 123 | $rootScope.$apply() 124 | } 125 | },time) 126 | } 127 | 128 | $timeout.cancel = function(id){ 129 | clearTimeout(id); 130 | } 131 | 132 | return new function(){ 133 | return $timeout; 134 | } 135 | }] 136 | } 137 | }) 138 | ``` 139 | ## $interval 140 | 141 | 他是用来代替 setInterval 的。 142 | 143 | 为什么要代替setInterval呢。 144 | 145 | 因为 setInterval 是一个 异步操作 会绕开 angular 控制里面的自动脏检查机制。 146 | 147 | 那么 $interval 就实现了 在异步操作里面自动脏检查。 148 | 149 | ### 取消$interval 150 | ```javascript 151 | var timer = $interval(fn,1000); 152 | 153 | $interval.cancel(timer); 154 | ``` 155 | ### 尝试自己实现$interval 156 | 157 | 1. 原生 158 | ```javascript 159 | function $interval(fn,time){ 160 | return setInterval(function(){ 161 | try{ 162 | fn() 163 | }catch(error){ 164 | throw new Error(error); 165 | }finally{ 166 | $scope.$apply() 167 | } 168 | },time) 169 | } 170 | 171 | $interval.cancel = function(id){ 172 | clearInterval(id); 173 | } 174 | ``` 175 | 2. angularJS 176 | ```javascript 177 | angular.module('app',[]) 178 | .provider('interval',function(){ 179 | return { 180 | $get:['$rootScope',function($rootScope){ 181 | function $interval(fn,time){ 182 | return setInterval(function(){ 183 | try{ 184 | fn() 185 | }catch(error){ 186 | throw new Error(error); 187 | }finally{ 188 | $rootScope.$apply() 189 | } 190 | },time) 191 | } 192 | 193 | $interval.cancel = function(id){ 194 | clearInterval(id); 195 | } 196 | return new function(){ 197 | return $interval; 198 | } 199 | }] 200 | } 201 | }) 202 | ``` 203 | ## $location 204 | 205 | 他是用来代替 window.location 的。 206 | 207 | 因为 angularJS 里面 有 自带的 路由 ng-router。 208 | 209 | $location 能更好的为 angular 的路由服务。 -------------------------------------------------------------------------------- /3-angularJS-part1/5.angularJS-自定义服务.md: -------------------------------------------------------------------------------- 1 | # angularJS 五大服务 2 | 3 | angularJS 除了内置服务还 提供了我们自定义服务的接口 4 | 5 | ## 什么是服务 6 | 7 | 服务是 一个 对象 object 或者是 一个函数 function/Function。 (可以是构造函数) 8 | 9 | ## 1. constant 10 | 11 | 功能 : 定义一个全局常量 12 | 13 | ### 用法 : 14 | 15 | 全局多次需要复用的 常量需要提取到 constant 里面 16 | ```javascript 17 | angular.module('app',[]) 18 | .constant('yourServiceName',{ //第一个参数 是你的服务的名称 类型 string 19 | key1:'value', //第二个参数 是你服务的具体实现 类型 object 20 | key2:0, 21 | key3:true, 22 | key4:function(){}, 23 | key5:{}, 24 | key6:[] 25 | }) 26 | ``` 27 | ## 2. value 28 | 29 | 功能 : 定义一个全局变量 30 | 31 | ### 用法 : 32 | 33 | 全局多次需要复用的 变量需要提取到 value 里面 34 | ```javascript 35 | angular.module('app',[]) 36 | .value('yourServiceName',{ //第一个参数 是你的服务的名称 类型 string 37 | key1:'value', //第二个参数 是你服务的具体实现 类型 object 38 | key2:0, 39 | key3:true, 40 | key4:function(){}, 41 | key5:{}, 42 | key6:[] 43 | }) 44 | ``` 45 | 与 constant的区别 46 | 47 | 1. constant 能在 config 里面注入 value不能 48 | 49 | 2. constant 一般用来定义全局常量 value 一般用来定义全局变量 当然你不这样做也是可以的 50 | 51 | ## 3. service 52 | 53 | 功能: 他是一个构造函数 54 | 55 | ### 用法: 56 | ```javascript 57 | angular.module('app',[]) 58 | .service('yourSeriveName',['$http',function($http){ 59 | //第一个参函数是服务名称 string 60 | //第二个参数是服务的具体实现 function 61 | 62 | this.attributeName = string/boolean/function/object/number; 63 | 64 | }]) 65 | ``` 66 | 场合: 需要多次调用的构造函数 可以提取成 service //高复用 低耦合 67 | 68 | ## 4. factory 69 | 70 | 功能: 他是一个普通函数 71 | 72 | ### 用法: 73 | ```javascript 74 | angular.module('app',[]) 75 | .factory('yourServiceName',[function(){ //工厂函数 76 | return{ 77 | name:'zhangsan', 78 | age:18, 79 | work:function(){ 80 | console.log('go to work') 81 | }, 82 | certificate:[], 83 | isAdult:true 84 | } 85 | }]) 86 | ``` 87 | ## 5. provider 88 | 89 | 他是一个 供应商服务 90 | 91 | 他是一个 高阶函数 -> 高阶函数 就是 根据不同的参数返回不同的函数的函数 92 | 93 | 他能够返回 value factory service 能够代替他们的功能 94 | 95 | 96 | ### 用法 1 97 | ```javascript 98 | angular.module('app',[]) 99 | .provider('yourServiceName',function(){ 100 | return { 101 | $get:function(){ 102 | return { //返回 factory 103 | key:'value', 104 | fn:function(){ 105 | 106 | } 107 | } 108 | } 109 | } 110 | }) 111 | ``` 112 | ### 用法 2 113 | ```javascript 114 | angular.module('app',[]) 115 | .provider('yourServiceName',function(){ 116 | return { 117 | $get:function(){ 118 | return new function(){ //返回 service 119 | this.attributeName = string/boolean/function/object/number; 120 | } 121 | } 122 | } 123 | }) 124 | ``` 125 | 126 | ### 用法 3 127 | ```javascript 128 | angular.module('app',[]) 129 | .provider('yourServiceName',function(){ 130 | this.$get=function(){ 131 | return { //返回 factory 132 | key:'value', 133 | fn:function(){ 134 | 135 | } 136 | } 137 | } 138 | }) 139 | ``` 140 | 141 | ### 用法 4 142 | ```javascript 143 | angular.module('app',[]) 144 | .provider('yourServiceName',function(){ 145 | this.$get=function(){ 146 | return new function(){ //返回 service 147 | this.attributeName = string/boolean/function/object/number; 148 | } 149 | } 150 | }) 151 | ``` 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /3-angularJS-part1/6.angularJS-自定义指令.md: -------------------------------------------------------------------------------- 1 | # angular 自定义指令 2 | 3 | 1. 指令可以是一个模板 (用来提取多次复用的dom结构[html] 我们称之为 组件) 4 | 5 | 2. 也可是一个功能 (用来提取多次复用的 function[js] ) 6 | 7 | 3. api 8 | ```javascript 9 | angular.module('app',[]) 10 | .directive('directive',[function(){ 11 | return{ //返回 object 或者 function 12 | restrict:'ECMA', 13 | replace:true, 14 | priority:1,//默认是0 优先级越高 越先执行 15 | terminal:true, //默认false 如果设置为true 则会阻止比该指令优先级低的指令执行 16 | transclude:true, //默认是false //如果是true 并且 template 里边 含有ng-transclude 指令 那么父元素的内容将会被保存在 含有ng-transclude指令的元素内。 17 | template:'
自定义指令
', 18 | scope:{ 19 | a:'=', 20 | b:'@', 21 | c:'&' 22 | }, 23 | controller:[function(){ 24 | 25 | }], 26 | controllerAs:'controllerName', 27 | require:'?^ngModel', // require 属性能获取 绑定了 ngModel的元素的控制器并在link 函数的第四个参数中传入 28 | link:function(scope,element,attribue,ngModelController){ 29 | 30 | }, 31 | compile:function(){ 32 | return { 33 | pre:function(scope,element,attribue){ 34 | 35 | }, 36 | post:function(scope,element,attribue){ 37 | 38 | } 39 | } 40 | } 41 | } 42 | }]) 43 | ``` 44 | ## replace 45 | 46 | 默认是false 47 | 48 | 如果为true 将替换掉该指令所在的元素 49 | 50 | ## restrict 51 | 52 | type : string 53 | 54 | E element 55 | C class 56 | M 注释 1. replace true 2.按格式 57 | A attribute 例子:
58 | 59 | ## template 60 | 61 | type : string / function 62 | 63 | string : '
自定义指令
' (html 元素模板 一个字符串) 64 | ```js 65 | function : function($element,$attributes){ //必须在 replace 为false 的时候使用 66 | 67 | } 68 | ``` 69 | ## templateUrl 70 | 71 | type : string / function 72 | 73 | string : './directive.html' (html 元素模板 一个单独的html文件) 74 | ```js 75 | function : function($element,$attributes){ //必须在 replace 为false 的时候使用 76 | 77 | } 78 | ``` 79 | ## priority 80 | 81 | 默认是0 优先级越高 越先执行 82 | 83 | ## terminal 84 | 85 | 默认false 如果设置为true 则会阻止比该指令优先级低的指令执行 86 | 87 | ## transclude 88 | 89 | 默认是false 90 | 91 | 如果是true 并且 template 里边 含有ng-transclude 指令, 92 | 93 | 那么父元素的内容将会被保存在 含有ng-transclude指令的元素内。 94 | 95 | ## scope 96 | 97 | scope 默认值是 false 98 | 99 | scope : boolean / object 100 | 101 | 如果是 false 那么 将不新建自己的scope 使用 父元素的scope 102 | 如果是 true 那么 新建自己的scope 并且继承 父级的scope 103 | 104 | 如果是对象 那么新建自己的scope 并且 按你的意思来集成父元素的scope的某些属性或者一个都不继承 或者 单向绑定 或者 双向绑定 105 | 106 | { 107 | a:'=', // = 是双向绑定的意思 108 | b:'@' // @ 是单向绑定的意思 109 | c:'&' // & 传递function的 传递的时候需要 调用一下 然后呢 使用的时候也要调用一下 110 | } 111 | 112 | 使用'='时如何传递值 113 | 114 | 使用'@' 时如何传递值 使用b="data" 会把 data 识别为字符串 115 | 116 | 使用'&' 时如何传递值 117 | 118 | ## require 119 | require 属性能获取 绑定了 ngModel的元素的控制器并在link 函数的第四个参数中传入 120 | 121 | 在自定义指令中通常会出先一些通用的代码逻辑 为了不违反 DRY 原则 可以把这些逻辑写在同一个指令的控制器上 122 | 123 | 然后通过require 来获取 124 | 125 | 用法 require:'?^directiveName' 126 | 127 | 其中? 号表示 如果这个指令没有被找到 那么 将会传递一个 null 给link 的第四个参数 而不是undefined 128 | 129 | ^ 号表示 将会在本身和父指令上查找这个指令 130 | 131 | 不加任何修饰符表示只在指令本身查找被require的指令 132 | 133 | DRY(Don't repeat your self) 原则 134 | 135 | 在编码过程中不要出现重复代码,也就是要写出高复用,低耦合的代码。 136 | ## compile 137 | 138 | 他和link 的功能相似 但是 更加强大和复杂 139 | 140 | compile 顾名思义 是编译dom的 141 | 142 | 就是说 我们含有angular指令的dom 不能直接绑定到 dom 数上去 143 | 144 | 145 | 他有三个阶段 146 | 147 | 1. 预编译 return 之前 148 | 149 | 2. prelink 就是说当他在编译自己的时候触发的 如果在这个过程中 他发现了子指令那么接下来会运行子指令的 prelink 如此一直进行到最后一个子指令 pre 阶段完成 150 | 151 | 3. 当prelink 完成之后 会 从最后一个子指令的 postlink开始执行 让后依次向上执行postlink 直到 最大的父指令 完成 postlink 此时compile 结束 (可以在即将结束之前 把postlink当作 link 使用 故 link被屏蔽) 152 |        出现循环嵌套时,执行的顺序:1.先走父指令的return 之前的阶段 153 |                                 2.走父指令的prelink阶段 154 | 3.最后走父指令的link 155 | 156 | ## link 157 | 158 | 他提供了一个 修改dom的机会 在dom绑定到 dom树 之前 159 | 160 | function(scope,element,attribute){ 161 | 162 | } 163 | 164 | //compile 存在的时候会被屏蔽 165 | 166 | ## controllerAs 167 | 168 | 给匿名控制器命名 169 | 170 | 可以将数据挂载在这个别名上 再改控制器里面通过 this.attribute = $scope.data 来挂载 171 | 172 | 173 | 174 | ## demo1 175 | ```js 176 | .directive('ngPlaceholder',function(){ 177 | return function($scope,$element,$attributes){ 178 | var value = $attributes['ngPlaceholder'] 179 | var valueStr = '$scope.'+value; 180 | $element[0].placeholder = eval(valueStr) 181 | } 182 | }) 183 | ``` 184 | ```html 185 |
186 | 187 |
188 | ``` 189 | 190 | ## demo2 191 | ```js 192 | .directive('getElement',[function(){ 193 | return function($scope,$element,$attributes){ 194 | $scope[$attributes['getElement']] = $element 195 | } 196 | }]) 197 | ``` -------------------------------------------------------------------------------- /3-angularJS-part1/7.angularJS-$q.md: -------------------------------------------------------------------------------- 1 | # angularJS $q 2 | 3 | angular里面用$q实现了promise思想。 4 | 5 | 他是用来以同步思想进行异步编程的工具。 6 | 7 | ## $q 是一个内置服务 8 | 9 | 通过依赖注入 $q 来获取它 10 | 11 | 它有三个状态 12 | 13 | 1. 等待状态 pending 14 | 15 | 2. 已完成 fulfilled 16 | 17 | 3. 已拒绝 rejected 18 | 19 | var defer = $q.defer(); //此时为 等待 20 | 21 | defer.resolve(); //此时为 已完成 22 | 23 | defer.reject(); //此时为 已拒绝 24 | 25 | ## 使用场景 26 | 27 | 比如我们进行 ajax 技术进行数据请求的时候 28 | 29 | 这个过程是 异步的 我们无法在 成功的回掉函数外面 return 我们想要的数据 (也就是无法以同步的代码风格获取数据) 30 | 31 | 而promise思想 解决了 以同步思想进行异步编程的问题。 32 | 33 | 34 | ## demo 35 | ```javascript 36 | .provider('ajax',function(){ 37 | 38 | return { 39 | $get:['$http','$q',function($http,$q){ 40 | 41 | function ajax(obj){ 42 | var defer = $q.defer() 43 | $http(obj) 44 | .then(function(result){ 45 | defer.resolve(result.data) 46 | },function(error){ 47 | defer.reject(error) 48 | }) 49 | return defer.promise.$$state; 50 | } 51 | 52 | return new function(){ 53 | return ajax; 54 | } 55 | }] 56 | } 57 | 58 | }) 59 | // in controller 60 | $scope.data = ajax({ 61 | url:'http://localhost:8080/goodslist', 62 | method:'GET' 63 | }) 64 | ``` -------------------------------------------------------------------------------- /3-angularJS-part1/8.angularJS-ngroute.md: -------------------------------------------------------------------------------- 1 | # angular 路由 ng-route 2 | 3 | 导言 : 能够从页面的一个视图跳转到另一个视图,对单页面应用来说是至关重要的。当页面变得越来越复杂时。我们需要一个合理的方式来管理用户在使用过程中看到的界面 --AnglarJS权威指南P98 4 | 5 | ## 如何使用 6 | 7 | 首先你需要 下载 angular-route.js 8 | 9 | 然后在 angular.js 的后面链接 angular-route.js 10 | 11 | 再开始写代码 12 | ```javascript 13 | angular.module('app',['ngRoute']) 14 | .controller('main',[function(){ 15 | 16 | }]) 17 | .config(['$routeProvider',function($routeProvider){ 18 | $routeProvider.when('/home',{ 19 | template:'
home
' 20 | }) 21 | .when('/about',{ 22 | template:'
about
' 23 | }) 24 | .when('/me',{ 25 | template:'
me
' 26 | }) 27 | .otherwise('/home') 28 | }]) 29 | ``` 30 | ```html 31 | 32 | 33 | 34 | 35 | 43 | 44 | 45 |
46 | home 47 | about 48 | me 49 |
50 | //显示template的容器 51 | 52 | 53 | 54 | 55 | ``` 56 | 57 | ## when 58 | 59 | 用来配置页面的 path 60 | 61 | 不同的path 对应不同的页面 62 | ```javascript 63 | $routeProvider 64 | .when('/home',{ 65 | template:'
home1111 {{msg}} {{homeController.value}} {{data.value}}
', 66 | controller:['$scope','ajax',function($scope,ajax){ 67 | $scope.msg = 'hello'; 68 | this.value = '控制器携带的变量'; 69 | $scope.data = ajax.get({ 70 | url:'http://localhost:8080/goodslist' 71 | }); 72 | }], 73 | controllerAs:'homeController', 74 | resolve:{ //就是定义一个服务 一般用来定义请求数据的服务 75 | ajax:['$http','$q',function($http,$q){ 76 | 77 | return { 78 | get:function(obj){ 79 | var defer = $q.defer() // 等待 80 | $http(obj) 81 | .then(function(result){ 82 | defer.resolve(result.data) //已完成 83 | },function(error){ 84 | defer.reject(error) //已拒绝 已失败 85 | }) 86 | return defer.promise.$$state; 87 | } 88 | } 89 | 90 | }] 91 | } 92 | }) 93 | .when('/about',{ 94 | template:'
about222
', 95 | redirectTo:'/home' 96 | }) 97 | .when('/me',{ 98 | template:'
me333
' 99 | }) 100 | .otherwise('/about'); 101 | ``` 102 | ## otherwise 103 | 104 | 显示默认页面 105 | 106 | ### template 107 | 108 | 你要显示的字符串网页模板 109 | 110 | ### templateUrl 111 | 112 | 你要显示的网页文件模板 113 | 114 | ### controller 115 | 116 | 网页模板对应的控制器 117 | 118 | ### controllerAs 119 | 120 | 控制器的别名 121 | 122 | 可以将数据挂载在 上面 然后再网页上使用 123 | 124 | demo 125 | ```javascript 126 | controllerAs:'controllerName' 127 | 128 | //in controller 129 | 130 | this.data = 'controllerData' 131 | 132 | //in template 133 | ``` 134 | ```html 135 | {{controllerName.data}} 136 | ``` 137 | 138 | ### redirectTo 139 | 140 | 网页重定向 当路由指向当前页面的时候 会转到 redirectTo 制定路劲的页面去 141 | 142 | ### resolve 143 | 144 | 在页面跳转之前加载数据 145 | 146 | 他的值是一个对象 147 | 148 | 这个对象的key 就是 服务名称 149 | 150 | value 就是服务的具体实现 151 | 152 | demo: 153 | ```javascript 154 | resolve:{ //就是定义一个服务 一般用来定义请求数据的服务 155 | ajax:['$http','$q',function($http,$q){ 156 | 157 | return { 158 | get:function(obj){ 159 | var defer = $q.defer() // 等待 160 | $http(obj) 161 | .then(function(result){ 162 | defer.resolve(result.data) //已完成 163 | },function(error){ 164 | defer.reject(error) //已拒绝 165 | }) 166 | return defer.promise.$$state; 167 | } 168 | } 169 | 170 | }] 171 | } 172 | ``` 173 | 174 | ## ng-view 175 | 176 | 他是一个在网页上使用的容器 177 | 178 | 用来规定 template 显示的位置 179 | 180 | ## #!/ 181 | 182 | home 183 | 184 | 跳转路由的链接 185 | 186 | #用来阻止浏览器刷新 187 | 188 | ## 总结 189 | 190 | 一、路由 191 | 192 | 1. 路由是为了实现 单页面应用页面切换的工具 193 | 194 | 2. 路由的 优点 不刷新浏览器 比自定义指令简单 195 | 196 | 二、$q 197 | 198 | 1.实现以同步的写法进行异步编程 199 | 200 | 2.是angular 对 promise 的实现 201 | 202 | 3.三种状态 等待 已解决 已失败 203 | 204 | 三、自定义服务 205 | 206 | 为了抽取 应用中 公用的方法 207 | 208 | 使多次出现的相同代码 抽离出来 只实现一次 多次复用 209 | 210 | 达到减少冗余代码的作用 211 | 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /3-angularJS-part1/9.angularJS-ngroute传参.md: -------------------------------------------------------------------------------- 1 | # ngRoute 传参 2 | 3 | ## 传递 4 | 5 | ### 1. 6 | ```html 7 | home 8 | ``` 9 | 10 | ### 2. 11 | ```html 12 |
me
13 | ``` 14 | ```javascript 15 | controller('main',['$scope','$location',function($scope,$location){ 16 | $scope.goTo=function(path){ 17 | var params; 18 | /*在这里制作 params*/ 19 | var fullUrl = path + params; 20 | $location.url(fullUrl); 21 | } 22 | }]) 23 | ``` 24 | ### 3. 25 | 26 | config 27 | ```javascript 28 | 29 | $routeProvider.when('/home/:username/:id',{ 30 | 31 | }) 32 | 33 | ``` 34 | ```html 35 | 36 | home 37 | 38 | ``` 39 | 40 | 41 | ## 接收 42 | 43 | ### 1. 44 | ```javascript 45 | 46 | controller:['$scope',function($scope){ 47 | var paramsStr = window.location.href.split('?')[1] 48 | }] 49 | 50 | ``` 51 | 这种方式只能接收地址栏原生写法参数 52 | 53 | ### 2. 54 | ```javascript 55 | 56 | controller:['$scope','$location',function($scope,$location){ 57 | $scope.data = $location.search(); 58 | }] 59 | 60 | ``` 61 | 这种方式只能接收地址栏原生写法参数 62 | 63 | ### 3. 64 | ```javascript 65 | 66 | controller:['$scope','$routeParams',function($scope,$routeParams){ 67 | $scope.data = $routeParams; 68 | }] 69 | 70 | ``` 71 | 这种方式可接收通过when方法里配置的地址栏参数 72 | -------------------------------------------------------------------------------- /3-angularJS-part1/A.angularJS-ngroute-Events.md: -------------------------------------------------------------------------------- 1 | # angularJS ngRoute Events 2 | 3 | # Let's start 4 | 5 | ```js 6 | angular.module('app',[]).run(['$rootScope',function($rootScope){ 7 | 8 | $rootScope.$on('$routeChangeStart',function(event,currentRoute,previousRoute){ 9 | // 第一个参数是 事件对象 10 | // 第二个参数是 当前路由 11 | // 第三个参数是 上一个路由 12 | }) 13 | 14 | $rootScope.$on('$routeChangeSuccess',function(event,currentRoute,previousRoute){ 15 | $rootScope.path = currentRoute.$$route.originalPath //在路由跳转成功以后获取路由路径 存储在$rootScope.path 里 16 | }) 17 | 18 | $rootScope.$on('$routeChangeError',function(event,currentRoute,previousRoute,error){ 19 | //第四个参数是 错误信息 20 | }) 21 | 22 | $rootScope.$on('$routeUpdate',function(event,currentRoute){ 23 | // 触发条件 24 | // 1、将 路由内 reloadOnSearch 属性设置为 false 25 | // 2、改变路由参数 也就是hash 中 ? 以后的 内容. 26 | }) 27 | }]) 28 | ``` 29 | 30 | # demo (这是一个ngRoute路由自动替换选中样式的demo) 31 | 32 | ```html 33 | 34 | 35 | 36 | 37 | 38 | 39 | Document 40 | 45 | 46 | 47 | home 48 | about 49 | me 50 | 51 | 52 | 53 | 54 | 55 | 94 | ``` 95 | -------------------------------------------------------------------------------- /3-angularJS-part1/B.angularJS-ui-router.md: -------------------------------------------------------------------------------- 1 | # angularJS ui.router 2 | 3 | ## ui.router 与 ngRoute 的功能相似 4 | 5 | 区别是ui.router 能进行路由嵌套 ngRoute不行 6 | 7 | ## 如何使用 8 | 9 | 1. 下载angular-ui-router.js 10 | 11 | 2. 引入 12 | 13 | 3. 依赖注入 angular.module('app',['ui.router']); 14 | 15 | ## demo 16 | 17 | ```html 18 | 19 | 20 | 21 | 22 | 23 | 24 | Document 25 | 37 | 38 | 39 | 40 | 41 |
42 |
home
43 |
about
44 |
me
45 | 46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 105 | ``` 106 | -------------------------------------------------------------------------------- /3-angularJS-part1/C.angularJS-ui-router-events.md: -------------------------------------------------------------------------------- 1 | # ui.router 路由事件 2 | 3 | ## 准备 4 | 5 | 下载 6 | angular-ui-router.js 7 | stateEvents.js 8 | 9 | 引入 10 | ## 如何开始 11 | ```js 12 | angular.module('app',['ui.router','ui.router.state.events']) 13 | .config() //在这里面配置路由 14 | .run(['$rootScope',function($rootScope){ 15 | $rootScope.$on('stateChangeStart',function(event,currentRoute,currentParams,previousRoute,previousParams){ 16 | //点击路由 就会开始跳转 17 | 18 | }) 19 | $rootScope.$on('stateChangeCancel',function(){ //这个没有演示 20 | 21 | }) 22 | $rootScope.$on('stateChangeSuccess',function(event,currentRoute,currentParams,previousRoute,previousParams){ 23 | //点击路由 路由成功切换的时候出发 24 | }) 25 | $rootScope.$on('stateChangeError',function(event,currentRoute,currentParams,previousRoute,previousParams,error){ 26 | // 例子 当templateUrl 的模板没有实现 或者没有起http-server的时候会触发失败 27 | }) 28 | $rootScope.$on('stateNotFound',function(event,wantTo,previousRoute,params){ 29 | // 你在 ui-sref="没有在config里面的state()里面配置的路由的时候" 并且点击它的时候 会触发 30 | }) 31 | }]) 32 | ``` -------------------------------------------------------------------------------- /3-angularJS-part1/D.angularJS-ui-router传参.md: -------------------------------------------------------------------------------- 1 | # ui.router 传参 2 | 3 | ## 如何配置 4 | ```js 5 | $stateProvider.state('home',{ 6 | params:{ 7 | key:'默认参数' 8 | } 9 | }) 10 | ``` 11 | ## 如何传递 12 | ```html 13 |
home
14 | ``` 15 | ## 如何接收 16 | 在接收参数的路由页面的控制器里 17 | ```js 18 | controller:['$stateParams','$scope',function($stateParams,$scope){ 19 | //this.data = $stateParams 20 | //$scope.data = $stateParams 21 | //console.log($stateParams) 22 | }] 23 | ``` -------------------------------------------------------------------------------- /3-angularJS-part1/E.angularJS-内置事件.md: -------------------------------------------------------------------------------- 1 | # angular内置事件 2 | 3 | angular内置事件是angularJS自带的事件 不需要引入其他的JS文件。 4 | 5 | ## Event name 6 | ```js 7 | //1. '$locationChangeStart' 8 | //2. '$locationChangeSuccess' 9 | ``` 10 | 11 | ## 如何使用 (How to use it) 12 | 在任何可以注入$scope 或者 $rootScope的地方使用 13 | ```js 14 | $rootScope.$on('$locationChangeStart',function(event,newUrl,oldUrl,newState,oldState){ 15 | 16 | }) 17 | $rootScope.$on('$locationChangeSuccess',function(event,newUrl,oldUrl,newState,oldState){ 18 | 19 | }) 20 | // 或者你也可以使用 $scope 来监听 因为这个事件是通过$rootScope.$broadcast 来进行广播的 所以任何子作用域都能监听得到 21 | 22 | ``` -------------------------------------------------------------------------------- /4-angularJS-part2/1.angularJS自定义事件.md: -------------------------------------------------------------------------------- 1 | ## angularJS 自定义事件 2 | 3 | # $scope.$on 4 | 监听事件 5 | ```js 6 | $rootScope.$on('eventName',fn) 7 | // OR 8 | controller('main',['$scope',function($scope){ 9 | $scope.$on('eventName',function(event,data){ 10 | console.log(data) 11 | }) 12 | }]) 13 | ``` 14 | # $scope.$emit 15 | 向上冒泡事件 16 | ```js 17 | controller('sonController',['$scope',function($scope){ 18 | $scope.$emit('eventName',{ //向上冒泡事件 19 | data:[] 20 | }) 21 | }]) 22 | 23 | controller('faterController',['$scope',function($scope){ 24 | $scope.$on('eventName',function(event,data){ //监听事件 25 | console.log(data) 26 | }) 27 | }]) 28 | ``` 29 | 30 | # $scope.$broadcast 31 | 向下广播事件 32 | ```js 33 | controller('sonController',['$scope',function($scope){ 34 | $scope.$on('eventName',function(event,data){ //监听事件 35 | console.log(data) 36 | }) 37 | }]) 38 | 39 | controller('faterController',['$scope',function($scope){ 40 | $scope.$broadcast('eventName',{ //向下广播事件 41 | data:[] 42 | }) 43 | }]) 44 | //OR 45 | $rootScope.$broadcast(eventName,{key:value}) 46 | ``` -------------------------------------------------------------------------------- /4-angularJS-part2/2.my-click.md: -------------------------------------------------------------------------------- 1 | ## 尝试自己实现 my-click 2 | 3 | ```html 4 |
按钮
5 | ``` 6 | 首先来实现一种原生的 7 | ```js 8 | angular.module('app',[]) 9 | .controller('main',['$scope',function($scope){ 10 | $scope.fn = function(){ 11 | console.log('已点击') 12 | } 13 | }]) 14 | .directive('myClick',[function(){ 15 | return function(scope,ele,attr){ 16 | ele.bind('click',fn) // ele 是一个简易jquery对象 里面有绑定该指令的元素的元素 17 | function fn(event){ 18 | //在这里调用$scope里面的函数 19 | //期望调用 $scope.fn() <- eval('$scope.fn()') 20 | 21 | var jsCode = '$scope.'+attr['myClick']+';' //attr是绑定了该指令的元素的所有的属性对象 22 | 23 | scope.$event = event; 24 | 25 | eval(jsCode); //在调用之前应在scope下实现 $event 对象 26 | 27 | } 28 | } 29 | }]) 30 | 31 | ``` 32 | 33 | 再实现一种angular的 34 | 35 | ```js 36 | .directive('myClick',[function(){ 37 | return function(scope,ele,attr){ 38 | ele.on('click',function(event){ 39 | scope.$event = event; 40 | scope.$apply(attr['myClick']); 41 | }) 42 | } 43 | }]) 44 | ``` -------------------------------------------------------------------------------- /4-angularJS-part2/3.集成bootStrap.md: -------------------------------------------------------------------------------- 1 | # 集成 ui.bootstrap 2 | 前言: ui.bootstrap 是一个支持 pc端的angularJS 组件库。 3 | 注意: 版本号必须配套 4 | 5 | ## 准备工作 6 | ``` 7 | 1、 npm i angular@1.6.1 --save-dev 8 | 2、 npm i angular-ui-bootstrap --save-dev 9 | 3、 npm i bootstrap@3.3.7 --save-dev 10 | 4、 npm i angular-animate@1.6.1 --save-dev 11 | ``` 12 | ## 1. 链接 bootstrap.css 13 | ```html 14 | 15 | 16 | ``` 17 | 18 | ## 2. 引入 script 19 | ```html 20 | 21 | 22 | 23 | ``` 24 | 25 | ## 3. 依赖注入 26 | ```js 27 | angular.module('bootstrapApp', ['ui.bootstrap','ngAnimate']) 28 | 29 | angular.bootstrap(document.documentElement, ['bootstrapApp']) //不需要写 ng-app 这个指令 30 | ``` 31 | -------------------------------------------------------------------------------- /4-angularJS-part2/4.$watch的使用.md: -------------------------------------------------------------------------------- 1 | # angular $watch的使用 2 | 3 | $watch 是一个监听$scope或者$rootScope属性值改变的函数。 4 | 5 | ## 例子 6 | ```js 7 | $scope.attr = 'hello'; 8 | $scope.$watch('attr',function(newVal,oldVal){ 9 | console.log('$scope.attr 的值有更新'); 10 | }) 11 | 12 | //$watch 接收2个参数 第一个参数是$scope下面的属性名称,第二个参数是一个回调函数 该函数会在 被监听的属性的值发生改变的时候调用。 13 | 14 | //你可以加一个$timeout来试试它 15 | $timeout(function(){ 16 | $scope.attr = 'new value'; 17 | },2000) //也就是说2秒之后会触发 $scope.$watch('attr',fn) 这个回调。 18 | 19 | ``` -------------------------------------------------------------------------------- /4-angularJS-part2/5.angular-api.md: -------------------------------------------------------------------------------- 1 | # angular 对象下的属性 2 | 3 | ## 1. module 4 | 这个属性是用来实现各个模块的 也就是angular实现的模块化 5 | 6 | ## 2. bootStrap 7 | 这个属性是用来启动bootStrap的 8 | 9 | # 以上的我们都知道 那么重点来了 10 | 11 | # 3. element 12 | 这个属性类似于 jquery 13 | ```js 14 | //1 15 | angular.element('
文本节点
') // => $(
文本节点
') 16 | 17 | //2 18 | angular.element(document.documentElement).append() // => $('html').append() 19 | 20 | //3 21 | angular.element(document.documentElement).find() // => $('html').find() 22 | 23 | //类似这样的jquery API还有很多就不一一列举了 比如 css 啥的 但是他不能代替jquery 它只是一个简单的jqList 比如后代选择器 class 选择器 还有animate 这些 接口 angular.elemnt()都没有实现 24 | 25 | ``` 26 | 27 | ## angular.forEach 28 | 这个方式用来在低端浏览器 使用forEach方法 如果浏览器支持es5 就不要考虑了 29 | ```js 30 | angular.forEach([1,2,3],function(value,index,array){ 31 | 32 | }) 33 | ``` 34 | ## angular 还有很多判断 对象类型的 api 35 | 比如 36 | ```js 37 | angular.isArray 38 | angular.isDate 39 | angular.isDefined 40 | angular.isElement 41 | angular.isFunction 42 | angular.isNumber 43 | angular.isObject 44 | angular.isString 45 | angular.isUndefined 46 | //---------------------- 47 | angular.equals //判断是否相等 48 | //----------------------- 49 | ``` 50 | ## angular 还有类型转换api 和字母大小写转换api 51 | 比如 52 | 53 | 字母大小写转换api 54 | ```js 55 | angular.lowercase 56 | angular.uppercase 57 | ``` 58 | 类型转换api 59 | ```js 60 | angular.fromJson 61 | angular.toJson 62 | ``` 63 | ## angular 依赖注入api 64 | 它提供了另一种依赖注入的方式 65 | ```js 66 | angular.injector 67 | ``` 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /4-angularJS-part2/6.集成ionic1.x.md: -------------------------------------------------------------------------------- 1 | # ionic 2 | 前言: ionic1.x 是一个 支持手机端的 组件库。 3 | 我们这里介绍 支持 angularJS 1.3.x 的ionic 4 | 5 | ## 如何集成: 6 | 7 | ### 1.下载 ionic1.x 8 | 9 | git clone git@github.com:ionic-team/ionic-v1.git 10 | 11 | ### 2.找到仓库里的release 引入里面的ionic.css和把fonts文件夹放在你项目的css文件夹同级目录 12 | ```html 13 | 14 | ``` 15 | 16 | ### 3.引入 ionic.bundle.js 17 | 注意: 在这之前需要引入 angular.js 最好是1.3.3版本的 18 | ```js 19 | /*v1.3.3*/ 20 | ``` 21 | 22 | ### 4.引入 ionic.js 23 | ```js 24 | /*v1.3.3*/ 25 | ``` 26 | 27 | ### 5.引入 ionic-angular.js 28 | ```js 29 | /*v1.3.3*/ 30 | ``` 31 | 32 | ### 6.依赖注入 33 | ```js 34 | angular.module('app',['ionic']) 35 | ``` -------------------------------------------------------------------------------- /4-angularJS-part2/7.$style和移动端点击事件的封装.md: -------------------------------------------------------------------------------- 1 | ```js 2 | .factory('$style', function () { 3 | 4 | function fn(dom, attributeName) { 5 | 6 | var value = window.getComputedStyle ? window.getComputedStyle(dom, null)[attributeName] : dom.currentStyle[attributeName]; 7 | 8 | return value 9 | } 10 | 11 | return fn 12 | }) 13 | 14 | .directive("ngTouchstart", function () { 15 | return { 16 | controller: ["$scope", "$element", function ($scope, $element) { 17 | $element.bind("touchstart", onTouchStart); 18 | function onTouchStart(event) { 19 | $scope.$event = event; 20 | var method = $element.attr("ng-touchstart"); 21 | $scope.$apply(method); 22 | } 23 | }] 24 | } 25 | }) 26 | .directive("ngTouchmove", function () { 27 | 28 | return { 29 | controller: ["$scope", "$element", function ($scope, $element) { 30 | 31 | $element.bind("touchstart", onTouchStart); 32 | function onTouchStart(event) { 33 | $scope.$event = event; 34 | $scope.$$firstTarget = event.target; 35 | event.preventDefault(); 36 | $element.bind("touchmove", onTouchMove); 37 | $element.bind("touchend", onTouchEnd); 38 | } 39 | function onTouchMove(event) { 40 | $scope.$$lastTarget = document.elementFromPoint(event.touches[0].pageX, event.touches[0].pageY); 41 | $scope.$event = event; 42 | var method = $element.attr("ng-touchmove"); 43 | $scope.$apply(method); 44 | } 45 | function onTouchEnd(event) { 46 | $scope.$event = event; 47 | event.preventDefault(); 48 | $element.unbind("touchmove", onTouchMove); 49 | $element.unbind("touchend", onTouchEnd); 50 | } 51 | 52 | }] 53 | } 54 | }) 55 | .directive("ngTouchend", function () { 56 | return { 57 | controller: ["$scope", "$element", function ($scope, $element) { 58 | 59 | $element.bind("touchend", onTouchEnd); 60 | 61 | function onTouchEnd(event) { 62 | $scope.$event = event; 63 | if ($scope.$$firstTarget == $scope.$$lastTarget) { 64 | var method = $element.attr("ng-touchend"); 65 | $scope.$apply(method); 66 | } else { 67 | var method = $element.attr("ng-touchend"); 68 | if(method.indexOf('()')==-1){ 69 | method = method.replace(')', ',"different")') 70 | }else{ 71 | method = method.replace(')', '"different")') 72 | } 73 | $scope.$apply(method); 74 | } 75 | } 76 | 77 | }] 78 | } 79 | }) 80 | 81 | ``` -------------------------------------------------------------------------------- /4-angularJS-part2/8.ionic轮播图实例.md: -------------------------------------------------------------------------------- 1 | # ionic 轮播图 2 | ```html 3 | 4 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 35 | 36 | 45 | ``` -------------------------------------------------------------------------------- /4-angularJS-part2/9.移动端手势初探.md: -------------------------------------------------------------------------------- 1 | # 手势 2 | 3 | 之前我们只实现了 touchstart touchmove touchend 当这3个指令联合使用的时候就构成了一个手势,但是一次绑定3个指令太麻烦能否集成为一个指令是这一节的内容。 4 | 5 | ## 定义手势 6 | ```js 7 | angular.module('app', []) 8 | .directive('ngGesture', function () { 9 | 10 | return function ($scope, $element, $attribute) { 11 | 12 | $element.bind('touchstart', function (event) { 13 | 14 | $scope.$event = event; 15 | 16 | var method = $attribute['ngGesture']; 17 | 18 | $scope.$apply(method) 19 | 20 | }) 21 | 22 | $element.bind('touchmove', function (event) { 23 | 24 | $scope.$event = event; 25 | 26 | var method = $attribute['ngGesture']; 27 | 28 | $scope.$apply(method) 29 | 30 | }) 31 | 32 | $element.bind('touchend', function (event) { 33 | 34 | $scope.$event = event; 35 | 36 | var method = $attribute['ngGesture']; 37 | 38 | $scope.$apply(method) 39 | 40 | }) 41 | 42 | } 43 | 44 | }) 45 | ``` 46 | ## 使用 47 | ```html 48 |
手势视图
49 | ``` 50 | ```C++ 51 | int main(){ 52 | int a = 10, b = 20; 53 | int sum( int a , int b){ 54 | return a+b; 55 | } 56 | return sum( a, b ); 57 | } 58 | ``` 59 | ```js 60 | angular.module('app', []) 61 | .controller('main', ['$scope', function ($scope) { 62 | 63 | $scope.gesture = function (event) { 64 | 65 | switch (event.type) { 66 | 67 | case 'touchstart': 68 | //在这里书写 touchstart 要做的事 69 | break; 70 | 71 | case 'touchmove': 72 | //在这里书写 touchmove 要做的事 73 | break; 74 | 75 | case 'touchend': 76 | //在这里书写 touchend 要做的事 77 | break; 78 | 79 | } 80 | 81 | } 82 | 83 | }]) 84 | ``` 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angularJS 2 | 3 | 这个仓库提供 git 使用教程 gulp 使用教程 angularJS 入门的教程。 4 | 5 | 仓库会不定期更新。 -------------------------------------------------------------------------------- /angularJS-tab切换/README.md: -------------------------------------------------------------------------------- 1 | # 简介(Abstract) 2 | 3 | 这是一个使用自定义指令+mock数据来实现tab切换的例子。 4 | 5 | this is a demo for achieve TabBar by directive and mockserver . 6 | 7 | ## 使用方法(Usage) 8 | 9 | git clone git@github.com:PsChina/angularJS.git 10 | 11 | cd angularJS-tab切换 12 | 13 | ### npm 14 | 15 | 1. npm i ↵ 16 | 17 | 2. gulp ↵ 18 | 19 | 3. open your browser open http://localhost:8080 20 | 21 | ### cnpm 22 | 23 | 1. cnpm i 回车 24 | 25 | 2. gulp 回车 26 | 27 | 3. 打开浏览器 输入 http://localhost:8080 回车 -------------------------------------------------------------------------------- /angularJS-tab切换/gulpfile.js: -------------------------------------------------------------------------------- 1 | var obj = [{ 2 | name:'热菜', 3 | value:[{ 4 | name:'西红柿炒鸡蛋', 5 | price:.1 6 | },{ 7 | name:'红烧肉', 8 | price:.2 9 | },{ 10 | name:'醋溜排骨', 11 | price:.3 12 | } 13 | ] 14 | },{ 15 | name:'凉菜', 16 | value:[{ 17 | name:'拍黄瓜', 18 | price:.4 19 | },{ 20 | name:'老醋花生', 21 | price:.5 22 | },{ 23 | name:'雪盖火焰山', 24 | price:.6 25 | }] 26 | },{ 27 | name:'甜点', 28 | value:[{ 29 | name:'拔丝香蕉', 30 | price:.7 31 | },{ 32 | name:'蛋挞', 33 | price:.8 34 | },{ 35 | name:'慕斯蛋糕', 36 | price:.9 37 | }] 38 | },{ 39 | name:'饮料', 40 | value:[{ 41 | name:'北冰洋', 42 | price:1 43 | },{ 44 | name:'橙汁', 45 | price:1.1 46 | },{ 47 | name:'青岛啤酒', 48 | price:1.2 49 | }] 50 | }] 51 | 52 | var gulp = require('gulp') 53 | 54 | var webserver = require('gulp-webserver') //这个启动后端服务器的 包 55 | 56 | var connect = require('gulp-connect') //这个是启动前端服务器的 包 57 | 58 | var urlTool = require('url'); 59 | 60 | var qs = require('qs'); 61 | 62 | gulp.task('mockServer',function(){ 63 | gulp.src('.') 64 | .pipe(webserver({ 65 | port:3000, 66 | middleware:function(req,res,next){ 67 | 68 | var method = req.method; 69 | 70 | var urlObj = urlTool.parse(req.url) 71 | 72 | var pathname = urlObj.pathname; 73 | 74 | res.setHeader('Access-Control-Allow-Origin','*') 75 | 76 | if(method == 'GET'){ 77 | 78 | switch (pathname) { 79 | case '/goodslist': 80 | res.setHeader('content-type','application/json;charset=utf-8') 81 | res.write(JSON.stringify(obj)); 82 | res.end(); 83 | break; 84 | 85 | default: 86 | break; 87 | } 88 | 89 | }else if(method == 'POST'){ 90 | 91 | var postParamsStr = ''; 92 | 93 | req.on('data',function(chunk){ 94 | postParamsStr +=chunk; 95 | }) 96 | 97 | req.on('end',function(){ 98 | 99 | 100 | var postParamsJson = 101 | 102 | postParamsStr.indexOf('{')!=-1&&postParamsStr.indexOf('}')!=-1 103 | 104 | ? 105 | 106 | JSON.parse(postParamsStr) 107 | 108 | : 109 | 110 | qs.parse(postParamsStr) 111 | 112 | 113 | 114 | 115 | switch (pathname) { 116 | case '/login': 117 | if(postParamsJson.userName == '张三' && postParamsJson.password==123456) { 118 | 119 | } 120 | break; 121 | case '/register': 122 | 123 | break; 124 | default: 125 | break; 126 | } 127 | }) 128 | 129 | 130 | 131 | 132 | } 133 | 134 | } 135 | })) 136 | }) 137 | 138 | 139 | gulp.task('httpServer',function(){ 140 | connect.server({ 141 | port:8080, 142 | livereload:true 143 | }) 144 | }) 145 | 146 | gulp.task('default',['mockServer','httpServer']) 147 | 148 | -------------------------------------------------------------------------------- /angularJS-tab切换/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /angularJS-tab切换/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ng-directive-tab", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "gulpfile.js", 6 | "dependencies": { 7 | "gulp":"^3.9.1", 8 | "gulp-connect":"^5.0.0", 9 | "gulp-webserver":"^0.9.1" 10 | }, 11 | "devDependencies": {}, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "author": "", 16 | "license": "ISC" 17 | } 18 | -------------------------------------------------------------------------------- /angularJS-tab切换/tab.html: -------------------------------------------------------------------------------- 1 |
2 | 34 |
35 |
36 | {{item.name}} 37 |
38 |
39 |
40 |
41 |
42 | {{cai.name}} 43 |
44 |
45 | {{cai.price | currency : '¥'}} 46 |
47 |
48 |
49 |
-------------------------------------------------------------------------------- /demos/多级联动筛选demo/selectfunc.js: -------------------------------------------------------------------------------- 1 | const serverMessage = { 2 | "success":true, 3 | "code":"0", 4 | "data": { 5 | "list": [ 6 | { 7 | "name":"检修电工", 8 | "select":false, 9 | "list": [ 10 | { 11 | "name":"检修班组一", 12 | "select":false, 13 | "list":[ 14 | { 15 | "id":"1", 16 | "name":"检修-赵工", 17 | "role":"E", 18 | "select":false, 19 | }, 20 | { 21 | "id":"2", 22 | "name":"检修-钱工", 23 | "role":"E", 24 | "select":false, 25 | } 26 | ] 27 | }, 28 | { 29 | name:"检修班组二", 30 | "select":false, 31 | "list":[ 32 | { 33 | "id":"3", 34 | "name":"检修-孙工", 35 | "role":"E", 36 | "select":false, 37 | }, 38 | { 39 | "id":"4", 40 | "name":"检修-李工", 41 | "role":"E", 42 | "select":false, 43 | } 44 | ] 45 | } 46 | 47 | ] 48 | }, 49 | { 50 | "name":"运行电工", 51 | "select":false, 52 | "list": [ 53 | { 54 | "id":"5", 55 | "name":"运行电工NO1", 56 | "role":"E", 57 | "select":false, 58 | }, 59 | { 60 | "id":"6", 61 | "name":"运行-张工", 62 | "role":"E", 63 | "select":false, 64 | } 65 | ] 66 | } 67 | ] 68 | } 69 | } 70 | 71 | 72 | function addSelectAttr(list){ 73 | if(Array.isArray(list)){ 74 | for(const item of list){ 75 | item.select = false; 76 | if(item['list']){ 77 | addSelectAttr(item.list) 78 | } 79 | } 80 | } 81 | } 82 | 83 | function changeSelectStatus(selectVal,item){ 84 | item.select = !item.select; //改变select状态 85 | if(item['list']){ 86 | if(Array.isArray(item.list)){ 87 | for(const subItem of item.list){ 88 | changeSelectStatus(item.select,subItem); 89 | } 90 | } 91 | } 92 | return item 93 | } 94 | 95 | function findId (item,selectedItemArr=[]) { 96 | if(item['id']){ 97 | selectedItemArr.push(item) 98 | }else{ 99 | if(item['list']){ 100 | for(const subItem of item.list){ 101 | findId(subItem,selectedItemArr); 102 | } 103 | } 104 | } 105 | return selectedItemArr 106 | } 107 | 108 | function filterDidSelect (list) { 109 | let resultList = []; 110 | for(const item of list){ 111 | if(item.select){ // select为true 表示已经选择 112 | resultList = resultList.concat( findId(item,resultList) ) 113 | }else{ // 查看子元素是被选择 114 | resultList = resultList.concat( filterDidSelect(item['list']?item.list:[]) ) 115 | } 116 | } 117 | let finallyItemArr = [] 118 | resultList.forEach((item)=>{ // 数组去重 119 | let ok = true; 120 | finallyItemArr.forEach((finallyItem)=>{ 121 | if(finallyItem.id === item.id){ 122 | ok = false; 123 | } 124 | }) 125 | if(ok){ 126 | delete item.select; 127 | finallyItemArr.push(item) 128 | } 129 | }) 130 | return finallyItemArr; 131 | } 132 | 133 | changeSelectStatus(true,serverMessage.data.list[Math.floor(Math.random()*2)]) // 测试 选择函数 134 | 135 | console.log(JSON.stringify(serverMessage)) 136 | 137 | const result = filterDidSelect(serverMessage.data.list) // 测试筛选函数 138 | 139 | console.log(result); // 输出结果 140 | -------------------------------------------------------------------------------- /nrm/nrm.md: -------------------------------------------------------------------------------- 1 | # nrm 2 | 3 | nrm 是一个npm的源管理工具 4 | 5 | ## 获取 6 | 7 | npm install nrm -g 8 | 9 | ## 使用 10 | 11 | ### nrm ls 12 | 13 | 查看所有源 14 | 15 | ### nrm test 16 | 17 | 测试各个源的链接延迟 18 | 19 | ### nrm use 20 | 21 | 切换到某个源 22 | 23 | 例如 nrm use cnpm 24 | 25 | ### nrm current 26 | 27 | 查看当前使用的源 28 | 29 | ### nrm help 30 | 31 | 查看所有nrm命令 32 | 33 | 34 | ### 后记 35 | cnpm 与 npm 的优劣 36 | 由于防火长城的存在 使得我们的一些npm包无法通过,导致下载失败,但cnpm使用了vpn(虚拟专用网络)绕开了防火长城 每15分钟会与npm保持同步 37 | cnpm的服务器在国内所以速度比较快 38 | npm 使用官网源 所以可以正常发布npm包 39 | 在使用cnpm时使用的不是 npm官网源 所以无法登录npm账号,也就无法发布npm包了。 40 | 41 | -------------------------------------------------------------------------------- /端口号被占用如何解决.md: -------------------------------------------------------------------------------- 1 | #1、使用netstat -nao 2 | 查看所有被使用的端口 以及它的PID 3 | 4 | #2、使用 taskkill -pid PID 5 | 比如 taskkill -pid 8036 6 | 7 | #3、强制删除命令 8 | taskkill /f -pid 8036 -------------------------------------------------------------------------------- /设计模式/1.单例设计模式.md: -------------------------------------------------------------------------------- 1 | # 单例 2 | 3 | 单例就是 打个比方 你有7个老婆 4 | 那么当这7个老婆的任何一个老婆叫老公的时候 指的都是你 5 | 但是除了你的7个老婆之外任何人叫老公指的都不是你 6 | 7 | ## js例子 8 | 9 | ```js 10 | function SingletonInstance() { 11 | if (!SingletonInstance.self) { 12 | this.name = 'zhangsan'; 13 | this.age = 19; 14 | SingletonInstance.self = this; 15 | } else { 16 | return SingletonInstance.self; 17 | } 18 | } 19 | 20 | var instanceA = new SingletonInstance() 21 | instanceA.name = 'wangwu' 22 | var instanceB = new SingletonInstance() 23 | 24 | console.log(instanceA === instanceB) // =>> true 25 | console.log(instanceA,instanceB) 26 | // =>> {"name":"wangwu","age":"19"} {"name":"wangwu","age":"19"} 27 | 28 | ``` 29 | 30 | [更多设计模式](https://github.com/PsChina/DesignPattern) -------------------------------------------------------------------------------- /跨域问题/iframe+window.name/READEME.md: -------------------------------------------------------------------------------- 1 | # window.name + iframe 解决跨域 2 | 3 | 大家请参考网上的[文章](https://www.cnblogs.com/zichi/p/4620656.html)。 4 | 5 | 6 | ```javascript 7 | ['文章使用php返回,我用的是node返回'] 8 | ``` 9 | 10 | ``` 11 | 这次跟新是我练习跨域的方式之后还会尝试 postMessage 的方式尝试跨域 至于注释以后有时间我会来整理。感谢大家的支持。 12 | ``` 13 | -------------------------------------------------------------------------------- /跨域问题/iframe+window.name/axios.js: -------------------------------------------------------------------------------- 1 | /* axios v0.18.0 | (c) 2018 by Matt Zabriskie */ 2 | (function webpackUniversalModuleDefinition(root, factory) { 3 | if(typeof exports === 'object' && typeof module === 'object') 4 | module.exports = factory(); 5 | else if(typeof define === 'function' && define.amd) 6 | define([], factory); 7 | else if(typeof exports === 'object') 8 | exports["axios"] = factory(); 9 | else 10 | root["axios"] = factory(); 11 | })(this, function() { 12 | return /******/ (function(modules) { // webpackBootstrap 13 | /******/ // The module cache 14 | /******/ var installedModules = {}; 15 | /******/ 16 | /******/ // The require function 17 | /******/ function __webpack_require__(moduleId) { 18 | /******/ 19 | /******/ // Check if module is in cache 20 | /******/ if(installedModules[moduleId]) 21 | /******/ return installedModules[moduleId].exports; 22 | /******/ 23 | /******/ // Create a new module (and put it into the cache) 24 | /******/ var module = installedModules[moduleId] = { 25 | /******/ exports: {}, 26 | /******/ id: moduleId, 27 | /******/ loaded: false 28 | /******/ }; 29 | /******/ 30 | /******/ // Execute the module function 31 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 32 | /******/ 33 | /******/ // Flag the module as loaded 34 | /******/ module.loaded = true; 35 | /******/ 36 | /******/ // Return the exports of the module 37 | /******/ return module.exports; 38 | /******/ } 39 | /******/ 40 | /******/ 41 | /******/ // expose the modules object (__webpack_modules__) 42 | /******/ __webpack_require__.m = modules; 43 | /******/ 44 | /******/ // expose the module cache 45 | /******/ __webpack_require__.c = installedModules; 46 | /******/ 47 | /******/ // __webpack_public_path__ 48 | /******/ __webpack_require__.p = ""; 49 | /******/ 50 | /******/ // Load entry module and return exports 51 | /******/ return __webpack_require__(0); 52 | /******/ }) 53 | /************************************************************************/ 54 | /******/ ([ 55 | /* 0 */ 56 | /***/ (function(module, exports, __webpack_require__) { 57 | 58 | module.exports = __webpack_require__(1); 59 | 60 | /***/ }), 61 | /* 1 */ 62 | /***/ (function(module, exports, __webpack_require__) { 63 | 64 | 'use strict'; 65 | 66 | var utils = __webpack_require__(2); 67 | var bind = __webpack_require__(3); 68 | var Axios = __webpack_require__(5); 69 | var defaults = __webpack_require__(6); 70 | 71 | /** 72 | * Create an instance of Axios 73 | * 74 | * @param {Object} defaultConfig The default config for the instance 75 | * @return {Axios} A new instance of Axios 76 | */ 77 | function createInstance(defaultConfig) { 78 | var context = new Axios(defaultConfig); 79 | var instance = bind(Axios.prototype.request, context); 80 | 81 | // Copy axios.prototype to instance 82 | utils.extend(instance, Axios.prototype, context); 83 | 84 | // Copy context to instance 85 | utils.extend(instance, context); 86 | 87 | return instance; 88 | } 89 | 90 | // Create the default instance to be exported 91 | var axios = createInstance(defaults); 92 | 93 | // Expose Axios class to allow class inheritance 94 | axios.Axios = Axios; 95 | 96 | // Factory for creating new instances 97 | axios.create = function create(instanceConfig) { 98 | return createInstance(utils.merge(defaults, instanceConfig)); 99 | }; 100 | 101 | // Expose Cancel & CancelToken 102 | axios.Cancel = __webpack_require__(23); 103 | axios.CancelToken = __webpack_require__(24); 104 | axios.isCancel = __webpack_require__(20); 105 | 106 | // Expose all/spread 107 | axios.all = function all(promises) { 108 | return Promise.all(promises); 109 | }; 110 | axios.spread = __webpack_require__(25); 111 | 112 | module.exports = axios; 113 | 114 | // Allow use of default import syntax in TypeScript 115 | module.exports.default = axios; 116 | 117 | 118 | /***/ }), 119 | /* 2 */ 120 | /***/ (function(module, exports, __webpack_require__) { 121 | 122 | 'use strict'; 123 | 124 | var bind = __webpack_require__(3); 125 | var isBuffer = __webpack_require__(4); 126 | 127 | /*global toString:true*/ 128 | 129 | // utils is a library of generic helper functions non-specific to axios 130 | 131 | var toString = Object.prototype.toString; 132 | 133 | /** 134 | * Determine if a value is an Array 135 | * 136 | * @param {Object} val The value to test 137 | * @returns {boolean} True if value is an Array, otherwise false 138 | */ 139 | function isArray(val) { 140 | return toString.call(val) === '[object Array]'; 141 | } 142 | 143 | /** 144 | * Determine if a value is an ArrayBuffer 145 | * 146 | * @param {Object} val The value to test 147 | * @returns {boolean} True if value is an ArrayBuffer, otherwise false 148 | */ 149 | function isArrayBuffer(val) { 150 | return toString.call(val) === '[object ArrayBuffer]'; 151 | } 152 | 153 | /** 154 | * Determine if a value is a FormData 155 | * 156 | * @param {Object} val The value to test 157 | * @returns {boolean} True if value is an FormData, otherwise false 158 | */ 159 | function isFormData(val) { 160 | return (typeof FormData !== 'undefined') && (val instanceof FormData); 161 | } 162 | 163 | /** 164 | * Determine if a value is a view on an ArrayBuffer 165 | * 166 | * @param {Object} val The value to test 167 | * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false 168 | */ 169 | function isArrayBufferView(val) { 170 | var result; 171 | if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { 172 | result = ArrayBuffer.isView(val); 173 | } else { 174 | result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer); 175 | } 176 | return result; 177 | } 178 | 179 | /** 180 | * Determine if a value is a String 181 | * 182 | * @param {Object} val The value to test 183 | * @returns {boolean} True if value is a String, otherwise false 184 | */ 185 | function isString(val) { 186 | return typeof val === 'string'; 187 | } 188 | 189 | /** 190 | * Determine if a value is a Number 191 | * 192 | * @param {Object} val The value to test 193 | * @returns {boolean} True if value is a Number, otherwise false 194 | */ 195 | function isNumber(val) { 196 | return typeof val === 'number'; 197 | } 198 | 199 | /** 200 | * Determine if a value is undefined 201 | * 202 | * @param {Object} val The value to test 203 | * @returns {boolean} True if the value is undefined, otherwise false 204 | */ 205 | function isUndefined(val) { 206 | return typeof val === 'undefined'; 207 | } 208 | 209 | /** 210 | * Determine if a value is an Object 211 | * 212 | * @param {Object} val The value to test 213 | * @returns {boolean} True if value is an Object, otherwise false 214 | */ 215 | function isObject(val) { 216 | return val !== null && typeof val === 'object'; 217 | } 218 | 219 | /** 220 | * Determine if a value is a Date 221 | * 222 | * @param {Object} val The value to test 223 | * @returns {boolean} True if value is a Date, otherwise false 224 | */ 225 | function isDate(val) { 226 | return toString.call(val) === '[object Date]'; 227 | } 228 | 229 | /** 230 | * Determine if a value is a File 231 | * 232 | * @param {Object} val The value to test 233 | * @returns {boolean} True if value is a File, otherwise false 234 | */ 235 | function isFile(val) { 236 | return toString.call(val) === '[object File]'; 237 | } 238 | 239 | /** 240 | * Determine if a value is a Blob 241 | * 242 | * @param {Object} val The value to test 243 | * @returns {boolean} True if value is a Blob, otherwise false 244 | */ 245 | function isBlob(val) { 246 | return toString.call(val) === '[object Blob]'; 247 | } 248 | 249 | /** 250 | * Determine if a value is a Function 251 | * 252 | * @param {Object} val The value to test 253 | * @returns {boolean} True if value is a Function, otherwise false 254 | */ 255 | function isFunction(val) { 256 | return toString.call(val) === '[object Function]'; 257 | } 258 | 259 | /** 260 | * Determine if a value is a Stream 261 | * 262 | * @param {Object} val The value to test 263 | * @returns {boolean} True if value is a Stream, otherwise false 264 | */ 265 | function isStream(val) { 266 | return isObject(val) && isFunction(val.pipe); 267 | } 268 | 269 | /** 270 | * Determine if a value is a URLSearchParams object 271 | * 272 | * @param {Object} val The value to test 273 | * @returns {boolean} True if value is a URLSearchParams object, otherwise false 274 | */ 275 | function isURLSearchParams(val) { 276 | return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams; 277 | } 278 | 279 | /** 280 | * Trim excess whitespace off the beginning and end of a string 281 | * 282 | * @param {String} str The String to trim 283 | * @returns {String} The String freed of excess whitespace 284 | */ 285 | function trim(str) { 286 | return str.replace(/^\s*/, '').replace(/\s*$/, ''); 287 | } 288 | 289 | /** 290 | * Determine if we're running in a standard browser environment 291 | * 292 | * This allows axios to run in a web worker, and react-native. 293 | * Both environments support XMLHttpRequest, but not fully standard globals. 294 | * 295 | * web workers: 296 | * typeof window -> undefined 297 | * typeof document -> undefined 298 | * 299 | * react-native: 300 | * navigator.product -> 'ReactNative' 301 | */ 302 | function isStandardBrowserEnv() { 303 | if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') { 304 | return false; 305 | } 306 | return ( 307 | typeof window !== 'undefined' && 308 | typeof document !== 'undefined' 309 | ); 310 | } 311 | 312 | /** 313 | * Iterate over an Array or an Object invoking a function for each item. 314 | * 315 | * If `obj` is an Array callback will be called passing 316 | * the value, index, and complete array for each item. 317 | * 318 | * If 'obj' is an Object callback will be called passing 319 | * the value, key, and complete object for each property. 320 | * 321 | * @param {Object|Array} obj The object to iterate 322 | * @param {Function} fn The callback to invoke for each item 323 | */ 324 | function forEach(obj, fn) { 325 | // Don't bother if no value provided 326 | if (obj === null || typeof obj === 'undefined') { 327 | return; 328 | } 329 | 330 | // Force an array if not already something iterable 331 | if (typeof obj !== 'object') { 332 | /*eslint no-param-reassign:0*/ 333 | obj = [obj]; 334 | } 335 | 336 | if (isArray(obj)) { 337 | // Iterate over array values 338 | for (var i = 0, l = obj.length; i < l; i++) { 339 | fn.call(null, obj[i], i, obj); 340 | } 341 | } else { 342 | // Iterate over object keys 343 | for (var key in obj) { 344 | if (Object.prototype.hasOwnProperty.call(obj, key)) { 345 | fn.call(null, obj[key], key, obj); 346 | } 347 | } 348 | } 349 | } 350 | 351 | /** 352 | * Accepts varargs expecting each argument to be an object, then 353 | * immutably merges the properties of each object and returns result. 354 | * 355 | * When multiple objects contain the same key the later object in 356 | * the arguments list will take precedence. 357 | * 358 | * Example: 359 | * 360 | * ```js 361 | * var result = merge({foo: 123}, {foo: 456}); 362 | * console.log(result.foo); // outputs 456 363 | * ``` 364 | * 365 | * @param {Object} obj1 Object to merge 366 | * @returns {Object} Result of all merge properties 367 | */ 368 | function merge(/* obj1, obj2, obj3, ... */) { 369 | var result = {}; 370 | function assignValue(val, key) { 371 | if (typeof result[key] === 'object' && typeof val === 'object') { 372 | result[key] = merge(result[key], val); 373 | } else { 374 | result[key] = val; 375 | } 376 | } 377 | 378 | for (var i = 0, l = arguments.length; i < l; i++) { 379 | forEach(arguments[i], assignValue); 380 | } 381 | return result; 382 | } 383 | 384 | /** 385 | * Extends object a by mutably adding to it the properties of object b. 386 | * 387 | * @param {Object} a The object to be extended 388 | * @param {Object} b The object to copy properties from 389 | * @param {Object} thisArg The object to bind function to 390 | * @return {Object} The resulting value of object a 391 | */ 392 | function extend(a, b, thisArg) { 393 | forEach(b, function assignValue(val, key) { 394 | if (thisArg && typeof val === 'function') { 395 | a[key] = bind(val, thisArg); 396 | } else { 397 | a[key] = val; 398 | } 399 | }); 400 | return a; 401 | } 402 | 403 | module.exports = { 404 | isArray: isArray, 405 | isArrayBuffer: isArrayBuffer, 406 | isBuffer: isBuffer, 407 | isFormData: isFormData, 408 | isArrayBufferView: isArrayBufferView, 409 | isString: isString, 410 | isNumber: isNumber, 411 | isObject: isObject, 412 | isUndefined: isUndefined, 413 | isDate: isDate, 414 | isFile: isFile, 415 | isBlob: isBlob, 416 | isFunction: isFunction, 417 | isStream: isStream, 418 | isURLSearchParams: isURLSearchParams, 419 | isStandardBrowserEnv: isStandardBrowserEnv, 420 | forEach: forEach, 421 | merge: merge, 422 | extend: extend, 423 | trim: trim 424 | }; 425 | 426 | 427 | /***/ }), 428 | /* 3 */ 429 | /***/ (function(module, exports) { 430 | 431 | 'use strict'; 432 | 433 | module.exports = function bind(fn, thisArg) { 434 | return function wrap() { 435 | var args = new Array(arguments.length); 436 | for (var i = 0; i < args.length; i++) { 437 | args[i] = arguments[i]; 438 | } 439 | return fn.apply(thisArg, args); 440 | }; 441 | }; 442 | 443 | 444 | /***/ }), 445 | /* 4 */ 446 | /***/ (function(module, exports) { 447 | 448 | /*! 449 | * Determine if an object is a Buffer 450 | * 451 | * @author Feross Aboukhadijeh 452 | * @license MIT 453 | */ 454 | 455 | // The _isBuffer check is for Safari 5-7 support, because it's missing 456 | // Object.prototype.constructor. Remove this eventually 457 | module.exports = function (obj) { 458 | return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) 459 | } 460 | 461 | function isBuffer (obj) { 462 | return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) 463 | } 464 | 465 | // For Node v0.10 support. Remove this eventually. 466 | function isSlowBuffer (obj) { 467 | return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) 468 | } 469 | 470 | 471 | /***/ }), 472 | /* 5 */ 473 | /***/ (function(module, exports, __webpack_require__) { 474 | 475 | 'use strict'; 476 | 477 | var defaults = __webpack_require__(6); 478 | var utils = __webpack_require__(2); 479 | var InterceptorManager = __webpack_require__(17); 480 | var dispatchRequest = __webpack_require__(18); 481 | 482 | /** 483 | * Create a new instance of Axios 484 | * 485 | * @param {Object} instanceConfig The default config for the instance 486 | */ 487 | function Axios(instanceConfig) { 488 | this.defaults = instanceConfig; 489 | this.interceptors = { 490 | request: new InterceptorManager(), 491 | response: new InterceptorManager() 492 | }; 493 | } 494 | 495 | /** 496 | * Dispatch a request 497 | * 498 | * @param {Object} config The config specific for this request (merged with this.defaults) 499 | */ 500 | Axios.prototype.request = function request(config) { 501 | /*eslint no-param-reassign:0*/ 502 | // Allow for axios('example/url'[, config]) a la fetch API 503 | if (typeof config === 'string') { 504 | config = utils.merge({ 505 | url: arguments[0] 506 | }, arguments[1]); 507 | } 508 | 509 | config = utils.merge(defaults, {method: 'get'}, this.defaults, config); 510 | config.method = config.method.toLowerCase(); 511 | 512 | // Hook up interceptors middleware 513 | var chain = [dispatchRequest, undefined]; 514 | var promise = Promise.resolve(config); 515 | 516 | this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { 517 | chain.unshift(interceptor.fulfilled, interceptor.rejected); 518 | }); 519 | 520 | this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { 521 | chain.push(interceptor.fulfilled, interceptor.rejected); 522 | }); 523 | 524 | while (chain.length) { 525 | promise = promise.then(chain.shift(), chain.shift()); 526 | } 527 | 528 | return promise; 529 | }; 530 | 531 | // Provide aliases for supported request methods 532 | utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { 533 | /*eslint func-names:0*/ 534 | Axios.prototype[method] = function(url, config) { 535 | return this.request(utils.merge(config || {}, { 536 | method: method, 537 | url: url 538 | })); 539 | }; 540 | }); 541 | 542 | utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { 543 | /*eslint func-names:0*/ 544 | Axios.prototype[method] = function(url, data, config) { 545 | return this.request(utils.merge(config || {}, { 546 | method: method, 547 | url: url, 548 | data: data 549 | })); 550 | }; 551 | }); 552 | 553 | module.exports = Axios; 554 | 555 | 556 | /***/ }), 557 | /* 6 */ 558 | /***/ (function(module, exports, __webpack_require__) { 559 | 560 | 'use strict'; 561 | 562 | var utils = __webpack_require__(2); 563 | var normalizeHeaderName = __webpack_require__(7); 564 | 565 | var DEFAULT_CONTENT_TYPE = { 566 | 'Content-Type': 'application/x-www-form-urlencoded' 567 | }; 568 | 569 | function setContentTypeIfUnset(headers, value) { 570 | if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) { 571 | headers['Content-Type'] = value; 572 | } 573 | } 574 | 575 | function getDefaultAdapter() { 576 | var adapter; 577 | if (typeof XMLHttpRequest !== 'undefined') { 578 | // For browsers use XHR adapter 579 | adapter = __webpack_require__(8); 580 | } else if (typeof process !== 'undefined') { 581 | // For node use HTTP adapter 582 | adapter = __webpack_require__(8); 583 | } 584 | return adapter; 585 | } 586 | 587 | var defaults = { 588 | adapter: getDefaultAdapter(), 589 | 590 | transformRequest: [function transformRequest(data, headers) { 591 | normalizeHeaderName(headers, 'Content-Type'); 592 | if (utils.isFormData(data) || 593 | utils.isArrayBuffer(data) || 594 | utils.isBuffer(data) || 595 | utils.isStream(data) || 596 | utils.isFile(data) || 597 | utils.isBlob(data) 598 | ) { 599 | return data; 600 | } 601 | if (utils.isArrayBufferView(data)) { 602 | return data.buffer; 603 | } 604 | if (utils.isURLSearchParams(data)) { 605 | setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); 606 | return data.toString(); 607 | } 608 | if (utils.isObject(data)) { 609 | setContentTypeIfUnset(headers, 'application/json;charset=utf-8'); 610 | return JSON.stringify(data); 611 | } 612 | return data; 613 | }], 614 | 615 | transformResponse: [function transformResponse(data) { 616 | /*eslint no-param-reassign:0*/ 617 | if (typeof data === 'string') { 618 | try { 619 | data = JSON.parse(data); 620 | } catch (e) { /* Ignore */ } 621 | } 622 | return data; 623 | }], 624 | 625 | /** 626 | * A timeout in milliseconds to abort a request. If set to 0 (default) a 627 | * timeout is not created. 628 | */ 629 | timeout: 0, 630 | 631 | xsrfCookieName: 'XSRF-TOKEN', 632 | xsrfHeaderName: 'X-XSRF-TOKEN', 633 | 634 | maxContentLength: -1, 635 | 636 | validateStatus: function validateStatus(status) { 637 | return status >= 200 && status < 300; 638 | } 639 | }; 640 | 641 | defaults.headers = { 642 | common: { 643 | 'Accept': 'application/json, text/plain, */*' 644 | } 645 | }; 646 | 647 | utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) { 648 | defaults.headers[method] = {}; 649 | }); 650 | 651 | utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { 652 | defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE); 653 | }); 654 | 655 | module.exports = defaults; 656 | 657 | 658 | /***/ }), 659 | /* 7 */ 660 | /***/ (function(module, exports, __webpack_require__) { 661 | 662 | 'use strict'; 663 | 664 | var utils = __webpack_require__(2); 665 | 666 | module.exports = function normalizeHeaderName(headers, normalizedName) { 667 | utils.forEach(headers, function processHeader(value, name) { 668 | if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { 669 | headers[normalizedName] = value; 670 | delete headers[name]; 671 | } 672 | }); 673 | }; 674 | 675 | 676 | /***/ }), 677 | /* 8 */ 678 | /***/ (function(module, exports, __webpack_require__) { 679 | 680 | 'use strict'; 681 | 682 | var utils = __webpack_require__(2); 683 | var settle = __webpack_require__(9); 684 | var buildURL = __webpack_require__(12); 685 | var parseHeaders = __webpack_require__(13); 686 | var isURLSameOrigin = __webpack_require__(14); 687 | var createError = __webpack_require__(10); 688 | var btoa = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || __webpack_require__(15); 689 | 690 | module.exports = function xhrAdapter(config) { 691 | return new Promise(function dispatchXhrRequest(resolve, reject) { 692 | var requestData = config.data; 693 | var requestHeaders = config.headers; 694 | 695 | if (utils.isFormData(requestData)) { 696 | delete requestHeaders['Content-Type']; // Let the browser set it 697 | } 698 | 699 | var request = new XMLHttpRequest(); 700 | var loadEvent = 'onreadystatechange'; 701 | var xDomain = false; 702 | 703 | // For IE 8/9 CORS support 704 | // Only supports POST and GET calls and doesn't returns the response headers. 705 | // DON'T do this for testing b/c XMLHttpRequest is mocked, not XDomainRequest. 706 | if (("production") !== 'test' && 707 | typeof window !== 'undefined' && 708 | window.XDomainRequest && !('withCredentials' in request) && 709 | !isURLSameOrigin(config.url)) { 710 | request = new window.XDomainRequest(); 711 | loadEvent = 'onload'; 712 | xDomain = true; 713 | request.onprogress = function handleProgress() {}; 714 | request.ontimeout = function handleTimeout() {}; 715 | } 716 | 717 | // HTTP basic authentication 718 | if (config.auth) { 719 | var username = config.auth.username || ''; 720 | var password = config.auth.password || ''; 721 | requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password); 722 | } 723 | 724 | request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true); 725 | 726 | // Set the request timeout in MS 727 | request.timeout = config.timeout; 728 | 729 | // Listen for ready state 730 | request[loadEvent] = function handleLoad() { 731 | if (!request || (request.readyState !== 4 && !xDomain)) { 732 | return; 733 | } 734 | 735 | // The request errored out and we didn't get a response, this will be 736 | // handled by onerror instead 737 | // With one exception: request that using file: protocol, most browsers 738 | // will return status as 0 even though it's a successful request 739 | if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { 740 | return; 741 | } 742 | 743 | // Prepare the response 744 | var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null; 745 | var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response; 746 | var response = { 747 | data: responseData, 748 | // IE sends 1223 instead of 204 (https://github.com/axios/axios/issues/201) 749 | status: request.status === 1223 ? 204 : request.status, 750 | statusText: request.status === 1223 ? 'No Content' : request.statusText, 751 | headers: responseHeaders, 752 | config: config, 753 | request: request 754 | }; 755 | 756 | settle(resolve, reject, response); 757 | 758 | // Clean up request 759 | request = null; 760 | }; 761 | 762 | // Handle low level network errors 763 | request.onerror = function handleError() { 764 | // Real errors are hidden from us by the browser 765 | // onerror should only fire if it's a network error 766 | reject(createError('Network Error', config, null, request)); 767 | 768 | // Clean up request 769 | request = null; 770 | }; 771 | 772 | // Handle timeout 773 | request.ontimeout = function handleTimeout() { 774 | reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', 775 | request)); 776 | 777 | // Clean up request 778 | request = null; 779 | }; 780 | 781 | // Add xsrf header 782 | // This is only done if running in a standard browser environment. 783 | // Specifically not if we're in a web worker, or react-native. 784 | if (utils.isStandardBrowserEnv()) { 785 | var cookies = __webpack_require__(16); 786 | 787 | // Add xsrf header 788 | var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ? 789 | cookies.read(config.xsrfCookieName) : 790 | undefined; 791 | 792 | if (xsrfValue) { 793 | requestHeaders[config.xsrfHeaderName] = xsrfValue; 794 | } 795 | } 796 | 797 | // Add headers to the request 798 | if ('setRequestHeader' in request) { 799 | utils.forEach(requestHeaders, function setRequestHeader(val, key) { 800 | if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') { 801 | // Remove Content-Type if data is undefined 802 | delete requestHeaders[key]; 803 | } else { 804 | // Otherwise add header to the request 805 | request.setRequestHeader(key, val); 806 | } 807 | }); 808 | } 809 | 810 | // Add withCredentials to request if needed 811 | if (config.withCredentials) { 812 | request.withCredentials = true; 813 | } 814 | 815 | // Add responseType to request if needed 816 | if (config.responseType) { 817 | try { 818 | request.responseType = config.responseType; 819 | } catch (e) { 820 | // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2. 821 | // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function. 822 | if (config.responseType !== 'json') { 823 | throw e; 824 | } 825 | } 826 | } 827 | 828 | // Handle progress if needed 829 | if (typeof config.onDownloadProgress === 'function') { 830 | request.addEventListener('progress', config.onDownloadProgress); 831 | } 832 | 833 | // Not all browsers support upload events 834 | if (typeof config.onUploadProgress === 'function' && request.upload) { 835 | request.upload.addEventListener('progress', config.onUploadProgress); 836 | } 837 | 838 | if (config.cancelToken) { 839 | // Handle cancellation 840 | config.cancelToken.promise.then(function onCanceled(cancel) { 841 | if (!request) { 842 | return; 843 | } 844 | 845 | request.abort(); 846 | reject(cancel); 847 | // Clean up request 848 | request = null; 849 | }); 850 | } 851 | 852 | if (requestData === undefined) { 853 | requestData = null; 854 | } 855 | 856 | // Send the request 857 | request.send(requestData); 858 | }); 859 | }; 860 | 861 | 862 | /***/ }), 863 | /* 9 */ 864 | /***/ (function(module, exports, __webpack_require__) { 865 | 866 | 'use strict'; 867 | 868 | var createError = __webpack_require__(10); 869 | 870 | /** 871 | * Resolve or reject a Promise based on response status. 872 | * 873 | * @param {Function} resolve A function that resolves the promise. 874 | * @param {Function} reject A function that rejects the promise. 875 | * @param {object} response The response. 876 | */ 877 | module.exports = function settle(resolve, reject, response) { 878 | var validateStatus = response.config.validateStatus; 879 | // Note: status is not exposed by XDomainRequest 880 | if (!response.status || !validateStatus || validateStatus(response.status)) { 881 | resolve(response); 882 | } else { 883 | reject(createError( 884 | 'Request failed with status code ' + response.status, 885 | response.config, 886 | null, 887 | response.request, 888 | response 889 | )); 890 | } 891 | }; 892 | 893 | 894 | /***/ }), 895 | /* 10 */ 896 | /***/ (function(module, exports, __webpack_require__) { 897 | 898 | 'use strict'; 899 | 900 | var enhanceError = __webpack_require__(11); 901 | 902 | /** 903 | * Create an Error with the specified message, config, error code, request and response. 904 | * 905 | * @param {string} message The error message. 906 | * @param {Object} config The config. 907 | * @param {string} [code] The error code (for example, 'ECONNABORTED'). 908 | * @param {Object} [request] The request. 909 | * @param {Object} [response] The response. 910 | * @returns {Error} The created error. 911 | */ 912 | module.exports = function createError(message, config, code, request, response) { 913 | var error = new Error(message); 914 | return enhanceError(error, config, code, request, response); 915 | }; 916 | 917 | 918 | /***/ }), 919 | /* 11 */ 920 | /***/ (function(module, exports) { 921 | 922 | 'use strict'; 923 | 924 | /** 925 | * Update an Error with the specified config, error code, and response. 926 | * 927 | * @param {Error} error The error to update. 928 | * @param {Object} config The config. 929 | * @param {string} [code] The error code (for example, 'ECONNABORTED'). 930 | * @param {Object} [request] The request. 931 | * @param {Object} [response] The response. 932 | * @returns {Error} The error. 933 | */ 934 | module.exports = function enhanceError(error, config, code, request, response) { 935 | error.config = config; 936 | if (code) { 937 | error.code = code; 938 | } 939 | error.request = request; 940 | error.response = response; 941 | return error; 942 | }; 943 | 944 | 945 | /***/ }), 946 | /* 12 */ 947 | /***/ (function(module, exports, __webpack_require__) { 948 | 949 | 'use strict'; 950 | 951 | var utils = __webpack_require__(2); 952 | 953 | function encode(val) { 954 | return encodeURIComponent(val). 955 | replace(/%40/gi, '@'). 956 | replace(/%3A/gi, ':'). 957 | replace(/%24/g, '$'). 958 | replace(/%2C/gi, ','). 959 | replace(/%20/g, '+'). 960 | replace(/%5B/gi, '['). 961 | replace(/%5D/gi, ']'); 962 | } 963 | 964 | /** 965 | * Build a URL by appending params to the end 966 | * 967 | * @param {string} url The base of the url (e.g., http://www.google.com) 968 | * @param {object} [params] The params to be appended 969 | * @returns {string} The formatted url 970 | */ 971 | module.exports = function buildURL(url, params, paramsSerializer) { 972 | /*eslint no-param-reassign:0*/ 973 | if (!params) { 974 | return url; 975 | } 976 | 977 | var serializedParams; 978 | if (paramsSerializer) { 979 | serializedParams = paramsSerializer(params); 980 | } else if (utils.isURLSearchParams(params)) { 981 | serializedParams = params.toString(); 982 | } else { 983 | var parts = []; 984 | 985 | utils.forEach(params, function serialize(val, key) { 986 | if (val === null || typeof val === 'undefined') { 987 | return; 988 | } 989 | 990 | if (utils.isArray(val)) { 991 | key = key + '[]'; 992 | } else { 993 | val = [val]; 994 | } 995 | 996 | utils.forEach(val, function parseValue(v) { 997 | if (utils.isDate(v)) { 998 | v = v.toISOString(); 999 | } else if (utils.isObject(v)) { 1000 | v = JSON.stringify(v); 1001 | } 1002 | parts.push(encode(key) + '=' + encode(v)); 1003 | }); 1004 | }); 1005 | 1006 | serializedParams = parts.join('&'); 1007 | } 1008 | 1009 | if (serializedParams) { 1010 | url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; 1011 | } 1012 | 1013 | return url; 1014 | }; 1015 | 1016 | 1017 | /***/ }), 1018 | /* 13 */ 1019 | /***/ (function(module, exports, __webpack_require__) { 1020 | 1021 | 'use strict'; 1022 | 1023 | var utils = __webpack_require__(2); 1024 | 1025 | // Headers whose duplicates are ignored by node 1026 | // c.f. https://nodejs.org/api/http.html#http_message_headers 1027 | var ignoreDuplicateOf = [ 1028 | 'age', 'authorization', 'content-length', 'content-type', 'etag', 1029 | 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', 1030 | 'last-modified', 'location', 'max-forwards', 'proxy-authorization', 1031 | 'referer', 'retry-after', 'user-agent' 1032 | ]; 1033 | 1034 | /** 1035 | * Parse headers into an object 1036 | * 1037 | * ``` 1038 | * Date: Wed, 27 Aug 2014 08:58:49 GMT 1039 | * Content-Type: application/json 1040 | * Connection: keep-alive 1041 | * Transfer-Encoding: chunked 1042 | * ``` 1043 | * 1044 | * @param {String} headers Headers needing to be parsed 1045 | * @returns {Object} Headers parsed into an object 1046 | */ 1047 | module.exports = function parseHeaders(headers) { 1048 | var parsed = {}; 1049 | var key; 1050 | var val; 1051 | var i; 1052 | 1053 | if (!headers) { return parsed; } 1054 | 1055 | utils.forEach(headers.split('\n'), function parser(line) { 1056 | i = line.indexOf(':'); 1057 | key = utils.trim(line.substr(0, i)).toLowerCase(); 1058 | val = utils.trim(line.substr(i + 1)); 1059 | 1060 | if (key) { 1061 | if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) { 1062 | return; 1063 | } 1064 | if (key === 'set-cookie') { 1065 | parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]); 1066 | } else { 1067 | parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; 1068 | } 1069 | } 1070 | }); 1071 | 1072 | return parsed; 1073 | }; 1074 | 1075 | 1076 | /***/ }), 1077 | /* 14 */ 1078 | /***/ (function(module, exports, __webpack_require__) { 1079 | 1080 | 'use strict'; 1081 | 1082 | var utils = __webpack_require__(2); 1083 | 1084 | module.exports = ( 1085 | utils.isStandardBrowserEnv() ? 1086 | 1087 | // Standard browser envs have full support of the APIs needed to test 1088 | // whether the request URL is of the same origin as current location. 1089 | (function standardBrowserEnv() { 1090 | var msie = /(msie|trident)/i.test(navigator.userAgent); 1091 | var urlParsingNode = document.createElement('a'); 1092 | var originURL; 1093 | 1094 | /** 1095 | * Parse a URL to discover it's components 1096 | * 1097 | * @param {String} url The URL to be parsed 1098 | * @returns {Object} 1099 | */ 1100 | function resolveURL(url) { 1101 | var href = url; 1102 | 1103 | if (msie) { 1104 | // IE needs attribute set twice to normalize properties 1105 | urlParsingNode.setAttribute('href', href); 1106 | href = urlParsingNode.href; 1107 | } 1108 | 1109 | urlParsingNode.setAttribute('href', href); 1110 | 1111 | // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils 1112 | return { 1113 | href: urlParsingNode.href, 1114 | protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', 1115 | host: urlParsingNode.host, 1116 | search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', 1117 | hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', 1118 | hostname: urlParsingNode.hostname, 1119 | port: urlParsingNode.port, 1120 | pathname: (urlParsingNode.pathname.charAt(0) === '/') ? 1121 | urlParsingNode.pathname : 1122 | '/' + urlParsingNode.pathname 1123 | }; 1124 | } 1125 | 1126 | originURL = resolveURL(window.location.href); 1127 | 1128 | /** 1129 | * Determine if a URL shares the same origin as the current location 1130 | * 1131 | * @param {String} requestURL The URL to test 1132 | * @returns {boolean} True if URL shares the same origin, otherwise false 1133 | */ 1134 | return function isURLSameOrigin(requestURL) { 1135 | var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL; 1136 | return (parsed.protocol === originURL.protocol && 1137 | parsed.host === originURL.host); 1138 | }; 1139 | })() : 1140 | 1141 | // Non standard browser envs (web workers, react-native) lack needed support. 1142 | (function nonStandardBrowserEnv() { 1143 | return function isURLSameOrigin() { 1144 | return true; 1145 | }; 1146 | })() 1147 | ); 1148 | 1149 | 1150 | /***/ }), 1151 | /* 15 */ 1152 | /***/ (function(module, exports) { 1153 | 1154 | 'use strict'; 1155 | 1156 | // btoa polyfill for IE<10 courtesy https://github.com/davidchambers/Base64.js 1157 | 1158 | var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 1159 | 1160 | function E() { 1161 | this.message = 'String contains an invalid character'; 1162 | } 1163 | E.prototype = new Error; 1164 | E.prototype.code = 5; 1165 | E.prototype.name = 'InvalidCharacterError'; 1166 | 1167 | function btoa(input) { 1168 | var str = String(input); 1169 | var output = ''; 1170 | for ( 1171 | // initialize result and counter 1172 | var block, charCode, idx = 0, map = chars; 1173 | // if the next str index does not exist: 1174 | // change the mapping table to "=" 1175 | // check if d has no fractional digits 1176 | str.charAt(idx | 0) || (map = '=', idx % 1); 1177 | // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 1178 | output += map.charAt(63 & block >> 8 - idx % 1 * 8) 1179 | ) { 1180 | charCode = str.charCodeAt(idx += 3 / 4); 1181 | if (charCode > 0xFF) { 1182 | throw new E(); 1183 | } 1184 | block = block << 8 | charCode; 1185 | } 1186 | return output; 1187 | } 1188 | 1189 | module.exports = btoa; 1190 | 1191 | 1192 | /***/ }), 1193 | /* 16 */ 1194 | /***/ (function(module, exports, __webpack_require__) { 1195 | 1196 | 'use strict'; 1197 | 1198 | var utils = __webpack_require__(2); 1199 | 1200 | module.exports = ( 1201 | utils.isStandardBrowserEnv() ? 1202 | 1203 | // Standard browser envs support document.cookie 1204 | (function standardBrowserEnv() { 1205 | return { 1206 | write: function write(name, value, expires, path, domain, secure) { 1207 | var cookie = []; 1208 | cookie.push(name + '=' + encodeURIComponent(value)); 1209 | 1210 | if (utils.isNumber(expires)) { 1211 | cookie.push('expires=' + new Date(expires).toGMTString()); 1212 | } 1213 | 1214 | if (utils.isString(path)) { 1215 | cookie.push('path=' + path); 1216 | } 1217 | 1218 | if (utils.isString(domain)) { 1219 | cookie.push('domain=' + domain); 1220 | } 1221 | 1222 | if (secure === true) { 1223 | cookie.push('secure'); 1224 | } 1225 | 1226 | document.cookie = cookie.join('; '); 1227 | }, 1228 | 1229 | read: function read(name) { 1230 | var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); 1231 | return (match ? decodeURIComponent(match[3]) : null); 1232 | }, 1233 | 1234 | remove: function remove(name) { 1235 | this.write(name, '', Date.now() - 86400000); 1236 | } 1237 | }; 1238 | })() : 1239 | 1240 | // Non standard browser env (web workers, react-native) lack needed support. 1241 | (function nonStandardBrowserEnv() { 1242 | return { 1243 | write: function write() {}, 1244 | read: function read() { return null; }, 1245 | remove: function remove() {} 1246 | }; 1247 | })() 1248 | ); 1249 | 1250 | 1251 | /***/ }), 1252 | /* 17 */ 1253 | /***/ (function(module, exports, __webpack_require__) { 1254 | 1255 | 'use strict'; 1256 | 1257 | var utils = __webpack_require__(2); 1258 | 1259 | function InterceptorManager() { 1260 | this.handlers = []; 1261 | } 1262 | 1263 | /** 1264 | * Add a new interceptor to the stack 1265 | * 1266 | * @param {Function} fulfilled The function to handle `then` for a `Promise` 1267 | * @param {Function} rejected The function to handle `reject` for a `Promise` 1268 | * 1269 | * @return {Number} An ID used to remove interceptor later 1270 | */ 1271 | InterceptorManager.prototype.use = function use(fulfilled, rejected) { 1272 | this.handlers.push({ 1273 | fulfilled: fulfilled, 1274 | rejected: rejected 1275 | }); 1276 | return this.handlers.length - 1; 1277 | }; 1278 | 1279 | /** 1280 | * Remove an interceptor from the stack 1281 | * 1282 | * @param {Number} id The ID that was returned by `use` 1283 | */ 1284 | InterceptorManager.prototype.eject = function eject(id) { 1285 | if (this.handlers[id]) { 1286 | this.handlers[id] = null; 1287 | } 1288 | }; 1289 | 1290 | /** 1291 | * Iterate over all the registered interceptors 1292 | * 1293 | * This method is particularly useful for skipping over any 1294 | * interceptors that may have become `null` calling `eject`. 1295 | * 1296 | * @param {Function} fn The function to call for each interceptor 1297 | */ 1298 | InterceptorManager.prototype.forEach = function forEach(fn) { 1299 | utils.forEach(this.handlers, function forEachHandler(h) { 1300 | if (h !== null) { 1301 | fn(h); 1302 | } 1303 | }); 1304 | }; 1305 | 1306 | module.exports = InterceptorManager; 1307 | 1308 | 1309 | /***/ }), 1310 | /* 18 */ 1311 | /***/ (function(module, exports, __webpack_require__) { 1312 | 1313 | 'use strict'; 1314 | 1315 | var utils = __webpack_require__(2); 1316 | var transformData = __webpack_require__(19); 1317 | var isCancel = __webpack_require__(20); 1318 | var defaults = __webpack_require__(6); 1319 | var isAbsoluteURL = __webpack_require__(21); 1320 | var combineURLs = __webpack_require__(22); 1321 | 1322 | /** 1323 | * Throws a `Cancel` if cancellation has been requested. 1324 | */ 1325 | function throwIfCancellationRequested(config) { 1326 | if (config.cancelToken) { 1327 | config.cancelToken.throwIfRequested(); 1328 | } 1329 | } 1330 | 1331 | /** 1332 | * Dispatch a request to the server using the configured adapter. 1333 | * 1334 | * @param {object} config The config that is to be used for the request 1335 | * @returns {Promise} The Promise to be fulfilled 1336 | */ 1337 | module.exports = function dispatchRequest(config) { 1338 | throwIfCancellationRequested(config); 1339 | 1340 | // Support baseURL config 1341 | if (config.baseURL && !isAbsoluteURL(config.url)) { 1342 | config.url = combineURLs(config.baseURL, config.url); 1343 | } 1344 | 1345 | // Ensure headers exist 1346 | config.headers = config.headers || {}; 1347 | 1348 | // Transform request data 1349 | config.data = transformData( 1350 | config.data, 1351 | config.headers, 1352 | config.transformRequest 1353 | ); 1354 | 1355 | // Flatten headers 1356 | config.headers = utils.merge( 1357 | config.headers.common || {}, 1358 | config.headers[config.method] || {}, 1359 | config.headers || {} 1360 | ); 1361 | 1362 | utils.forEach( 1363 | ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], 1364 | function cleanHeaderConfig(method) { 1365 | delete config.headers[method]; 1366 | } 1367 | ); 1368 | 1369 | var adapter = config.adapter || defaults.adapter; 1370 | 1371 | return adapter(config).then(function onAdapterResolution(response) { 1372 | throwIfCancellationRequested(config); 1373 | 1374 | // Transform response data 1375 | response.data = transformData( 1376 | response.data, 1377 | response.headers, 1378 | config.transformResponse 1379 | ); 1380 | 1381 | return response; 1382 | }, function onAdapterRejection(reason) { 1383 | if (!isCancel(reason)) { 1384 | throwIfCancellationRequested(config); 1385 | 1386 | // Transform response data 1387 | if (reason && reason.response) { 1388 | reason.response.data = transformData( 1389 | reason.response.data, 1390 | reason.response.headers, 1391 | config.transformResponse 1392 | ); 1393 | } 1394 | } 1395 | 1396 | return Promise.reject(reason); 1397 | }); 1398 | }; 1399 | 1400 | 1401 | /***/ }), 1402 | /* 19 */ 1403 | /***/ (function(module, exports, __webpack_require__) { 1404 | 1405 | 'use strict'; 1406 | 1407 | var utils = __webpack_require__(2); 1408 | 1409 | /** 1410 | * Transform the data for a request or a response 1411 | * 1412 | * @param {Object|String} data The data to be transformed 1413 | * @param {Array} headers The headers for the request or response 1414 | * @param {Array|Function} fns A single function or Array of functions 1415 | * @returns {*} The resulting transformed data 1416 | */ 1417 | module.exports = function transformData(data, headers, fns) { 1418 | /*eslint no-param-reassign:0*/ 1419 | utils.forEach(fns, function transform(fn) { 1420 | data = fn(data, headers); 1421 | }); 1422 | 1423 | return data; 1424 | }; 1425 | 1426 | 1427 | /***/ }), 1428 | /* 20 */ 1429 | /***/ (function(module, exports) { 1430 | 1431 | 'use strict'; 1432 | 1433 | module.exports = function isCancel(value) { 1434 | return !!(value && value.__CANCEL__); 1435 | }; 1436 | 1437 | 1438 | /***/ }), 1439 | /* 21 */ 1440 | /***/ (function(module, exports) { 1441 | 1442 | 'use strict'; 1443 | 1444 | /** 1445 | * Determines whether the specified URL is absolute 1446 | * 1447 | * @param {string} url The URL to test 1448 | * @returns {boolean} True if the specified URL is absolute, otherwise false 1449 | */ 1450 | module.exports = function isAbsoluteURL(url) { 1451 | // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). 1452 | // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed 1453 | // by any combination of letters, digits, plus, period, or hyphen. 1454 | return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); 1455 | }; 1456 | 1457 | 1458 | /***/ }), 1459 | /* 22 */ 1460 | /***/ (function(module, exports) { 1461 | 1462 | 'use strict'; 1463 | 1464 | /** 1465 | * Creates a new URL by combining the specified URLs 1466 | * 1467 | * @param {string} baseURL The base URL 1468 | * @param {string} relativeURL The relative URL 1469 | * @returns {string} The combined URL 1470 | */ 1471 | module.exports = function combineURLs(baseURL, relativeURL) { 1472 | return relativeURL 1473 | ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') 1474 | : baseURL; 1475 | }; 1476 | 1477 | 1478 | /***/ }), 1479 | /* 23 */ 1480 | /***/ (function(module, exports) { 1481 | 1482 | 'use strict'; 1483 | 1484 | /** 1485 | * A `Cancel` is an object that is thrown when an operation is canceled. 1486 | * 1487 | * @class 1488 | * @param {string=} message The message. 1489 | */ 1490 | function Cancel(message) { 1491 | this.message = message; 1492 | } 1493 | 1494 | Cancel.prototype.toString = function toString() { 1495 | return 'Cancel' + (this.message ? ': ' + this.message : ''); 1496 | }; 1497 | 1498 | Cancel.prototype.__CANCEL__ = true; 1499 | 1500 | module.exports = Cancel; 1501 | 1502 | 1503 | /***/ }), 1504 | /* 24 */ 1505 | /***/ (function(module, exports, __webpack_require__) { 1506 | 1507 | 'use strict'; 1508 | 1509 | var Cancel = __webpack_require__(23); 1510 | 1511 | /** 1512 | * A `CancelToken` is an object that can be used to request cancellation of an operation. 1513 | * 1514 | * @class 1515 | * @param {Function} executor The executor function. 1516 | */ 1517 | function CancelToken(executor) { 1518 | if (typeof executor !== 'function') { 1519 | throw new TypeError('executor must be a function.'); 1520 | } 1521 | 1522 | var resolvePromise; 1523 | this.promise = new Promise(function promiseExecutor(resolve) { 1524 | resolvePromise = resolve; 1525 | }); 1526 | 1527 | var token = this; 1528 | executor(function cancel(message) { 1529 | if (token.reason) { 1530 | // Cancellation has already been requested 1531 | return; 1532 | } 1533 | 1534 | token.reason = new Cancel(message); 1535 | resolvePromise(token.reason); 1536 | }); 1537 | } 1538 | 1539 | /** 1540 | * Throws a `Cancel` if cancellation has been requested. 1541 | */ 1542 | CancelToken.prototype.throwIfRequested = function throwIfRequested() { 1543 | if (this.reason) { 1544 | throw this.reason; 1545 | } 1546 | }; 1547 | 1548 | /** 1549 | * Returns an object that contains a new `CancelToken` and a function that, when called, 1550 | * cancels the `CancelToken`. 1551 | */ 1552 | CancelToken.source = function source() { 1553 | var cancel; 1554 | var token = new CancelToken(function executor(c) { 1555 | cancel = c; 1556 | }); 1557 | return { 1558 | token: token, 1559 | cancel: cancel 1560 | }; 1561 | }; 1562 | 1563 | module.exports = CancelToken; 1564 | 1565 | 1566 | /***/ }), 1567 | /* 25 */ 1568 | /***/ (function(module, exports) { 1569 | 1570 | 'use strict'; 1571 | 1572 | /** 1573 | * Syntactic sugar for invoking a function and expanding an array for arguments. 1574 | * 1575 | * Common use case would be to use `Function.prototype.apply`. 1576 | * 1577 | * ```js 1578 | * function f(x, y, z) {} 1579 | * var args = [1, 2, 3]; 1580 | * f.apply(null, args); 1581 | * ``` 1582 | * 1583 | * With `spread` this example can be re-written. 1584 | * 1585 | * ```js 1586 | * spread(function(x, y, z) {})([1, 2, 3]); 1587 | * ``` 1588 | * 1589 | * @param {Function} callback 1590 | * @returns {Function} 1591 | */ 1592 | module.exports = function spread(callback) { 1593 | return function wrap(arr) { 1594 | return callback.apply(null, arr); 1595 | }; 1596 | }; 1597 | 1598 | 1599 | /***/ }) 1600 | /******/ ]) 1601 | }); 1602 | ; 1603 | //# sourceMappingURL=axios.map -------------------------------------------------------------------------------- /跨域问题/iframe+window.name/empty/proxy.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /跨域问题/iframe+window.name/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /跨域问题/iframe+window.name/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "window.name", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.5", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 10 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 11 | "dev": true, 12 | "requires": { 13 | "mime-types": "~2.1.18", 14 | "negotiator": "0.6.1" 15 | } 16 | }, 17 | "array-flatten": { 18 | "version": "1.1.1", 19 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 20 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", 21 | "dev": true 22 | }, 23 | "asynckit": { 24 | "version": "0.4.0", 25 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 26 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 27 | }, 28 | "axios": { 29 | "version": "1.6.5", 30 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", 31 | "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", 32 | "requires": { 33 | "follow-redirects": "^1.15.4", 34 | "form-data": "^4.0.0", 35 | "proxy-from-env": "^1.1.0" 36 | } 37 | }, 38 | "body-parser": { 39 | "version": "1.18.2", 40 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", 41 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", 42 | "dev": true, 43 | "requires": { 44 | "bytes": "3.0.0", 45 | "content-type": "~1.0.4", 46 | "debug": "2.6.9", 47 | "depd": "~1.1.1", 48 | "http-errors": "~1.6.2", 49 | "iconv-lite": "0.4.19", 50 | "on-finished": "~2.3.0", 51 | "qs": "6.5.1", 52 | "raw-body": "2.3.2", 53 | "type-is": "~1.6.15" 54 | } 55 | }, 56 | "bytes": { 57 | "version": "3.0.0", 58 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 59 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", 60 | "dev": true 61 | }, 62 | "combined-stream": { 63 | "version": "1.0.8", 64 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 65 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 66 | "requires": { 67 | "delayed-stream": "~1.0.0" 68 | } 69 | }, 70 | "content-disposition": { 71 | "version": "0.5.2", 72 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 73 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", 74 | "dev": true 75 | }, 76 | "content-type": { 77 | "version": "1.0.4", 78 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 79 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 80 | "dev": true 81 | }, 82 | "cookie": { 83 | "version": "0.3.1", 84 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 85 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", 86 | "dev": true 87 | }, 88 | "cookie-signature": { 89 | "version": "1.0.6", 90 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 91 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", 92 | "dev": true 93 | }, 94 | "debug": { 95 | "version": "2.6.9", 96 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 97 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 98 | "dev": true, 99 | "requires": { 100 | "ms": "2.0.0" 101 | } 102 | }, 103 | "delayed-stream": { 104 | "version": "1.0.0", 105 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 106 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" 107 | }, 108 | "depd": { 109 | "version": "1.1.2", 110 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 111 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 112 | "dev": true 113 | }, 114 | "destroy": { 115 | "version": "1.0.4", 116 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 117 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", 118 | "dev": true 119 | }, 120 | "ee-first": { 121 | "version": "1.1.1", 122 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 123 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", 124 | "dev": true 125 | }, 126 | "encodeurl": { 127 | "version": "1.0.2", 128 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 129 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 130 | "dev": true 131 | }, 132 | "escape-html": { 133 | "version": "1.0.3", 134 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 135 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", 136 | "dev": true 137 | }, 138 | "etag": { 139 | "version": "1.8.1", 140 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 141 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 142 | "dev": true 143 | }, 144 | "express": { 145 | "version": "4.16.3", 146 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", 147 | "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", 148 | "dev": true, 149 | "requires": { 150 | "accepts": "~1.3.5", 151 | "array-flatten": "1.1.1", 152 | "body-parser": "1.18.2", 153 | "content-disposition": "0.5.2", 154 | "content-type": "~1.0.4", 155 | "cookie": "0.3.1", 156 | "cookie-signature": "1.0.6", 157 | "debug": "2.6.9", 158 | "depd": "~1.1.2", 159 | "encodeurl": "~1.0.2", 160 | "escape-html": "~1.0.3", 161 | "etag": "~1.8.1", 162 | "finalhandler": "1.1.1", 163 | "fresh": "0.5.2", 164 | "merge-descriptors": "1.0.1", 165 | "methods": "~1.1.2", 166 | "on-finished": "~2.3.0", 167 | "parseurl": "~1.3.2", 168 | "path-to-regexp": "0.1.7", 169 | "proxy-addr": "~2.0.3", 170 | "qs": "6.5.1", 171 | "range-parser": "~1.2.0", 172 | "safe-buffer": "5.1.1", 173 | "send": "0.16.2", 174 | "serve-static": "1.13.2", 175 | "setprototypeof": "1.1.0", 176 | "statuses": "~1.4.0", 177 | "type-is": "~1.6.16", 178 | "utils-merge": "1.0.1", 179 | "vary": "~1.1.2" 180 | } 181 | }, 182 | "finalhandler": { 183 | "version": "1.1.1", 184 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", 185 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", 186 | "dev": true, 187 | "requires": { 188 | "debug": "2.6.9", 189 | "encodeurl": "~1.0.2", 190 | "escape-html": "~1.0.3", 191 | "on-finished": "~2.3.0", 192 | "parseurl": "~1.3.2", 193 | "statuses": "~1.4.0", 194 | "unpipe": "~1.0.0" 195 | } 196 | }, 197 | "follow-redirects": { 198 | "version": "1.15.4", 199 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", 200 | "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==" 201 | }, 202 | "form-data": { 203 | "version": "4.0.0", 204 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 205 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 206 | "requires": { 207 | "asynckit": "^0.4.0", 208 | "combined-stream": "^1.0.8", 209 | "mime-types": "^2.1.12" 210 | } 211 | }, 212 | "forwarded": { 213 | "version": "0.1.2", 214 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 215 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", 216 | "dev": true 217 | }, 218 | "fresh": { 219 | "version": "0.5.2", 220 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 221 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 222 | "dev": true 223 | }, 224 | "http-errors": { 225 | "version": "1.6.3", 226 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", 227 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", 228 | "dev": true, 229 | "requires": { 230 | "depd": "~1.1.2", 231 | "inherits": "2.0.3", 232 | "setprototypeof": "1.1.0", 233 | "statuses": ">= 1.4.0 < 2" 234 | } 235 | }, 236 | "iconv-lite": { 237 | "version": "0.4.19", 238 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 239 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", 240 | "dev": true 241 | }, 242 | "inherits": { 243 | "version": "2.0.3", 244 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 245 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 246 | "dev": true 247 | }, 248 | "ipaddr.js": { 249 | "version": "1.6.0", 250 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", 251 | "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", 252 | "dev": true 253 | }, 254 | "media-typer": { 255 | "version": "0.3.0", 256 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 257 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 258 | "dev": true 259 | }, 260 | "merge-descriptors": { 261 | "version": "1.0.1", 262 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 263 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", 264 | "dev": true 265 | }, 266 | "methods": { 267 | "version": "1.1.2", 268 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 269 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 270 | "dev": true 271 | }, 272 | "mime": { 273 | "version": "1.4.1", 274 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 275 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", 276 | "dev": true 277 | }, 278 | "mime-db": { 279 | "version": "1.33.0", 280 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", 281 | "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" 282 | }, 283 | "mime-types": { 284 | "version": "2.1.18", 285 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", 286 | "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", 287 | "requires": { 288 | "mime-db": "~1.33.0" 289 | } 290 | }, 291 | "ms": { 292 | "version": "2.0.0", 293 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 294 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 295 | "dev": true 296 | }, 297 | "negotiator": { 298 | "version": "0.6.1", 299 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 300 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", 301 | "dev": true 302 | }, 303 | "on-finished": { 304 | "version": "2.3.0", 305 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 306 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 307 | "dev": true, 308 | "requires": { 309 | "ee-first": "1.1.1" 310 | } 311 | }, 312 | "parseurl": { 313 | "version": "1.3.2", 314 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 315 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", 316 | "dev": true 317 | }, 318 | "path-to-regexp": { 319 | "version": "0.1.7", 320 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 321 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", 322 | "dev": true 323 | }, 324 | "proxy-addr": { 325 | "version": "2.0.3", 326 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", 327 | "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", 328 | "dev": true, 329 | "requires": { 330 | "forwarded": "~0.1.2", 331 | "ipaddr.js": "1.6.0" 332 | } 333 | }, 334 | "proxy-from-env": { 335 | "version": "1.1.0", 336 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 337 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 338 | }, 339 | "qs": { 340 | "version": "6.5.1", 341 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 342 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", 343 | "dev": true 344 | }, 345 | "range-parser": { 346 | "version": "1.2.0", 347 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 348 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", 349 | "dev": true 350 | }, 351 | "raw-body": { 352 | "version": "2.3.2", 353 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", 354 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", 355 | "dev": true, 356 | "requires": { 357 | "bytes": "3.0.0", 358 | "http-errors": "1.6.2", 359 | "iconv-lite": "0.4.19", 360 | "unpipe": "1.0.0" 361 | }, 362 | "dependencies": { 363 | "depd": { 364 | "version": "1.1.1", 365 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 366 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", 367 | "dev": true 368 | }, 369 | "http-errors": { 370 | "version": "1.6.2", 371 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 372 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 373 | "dev": true, 374 | "requires": { 375 | "depd": "1.1.1", 376 | "inherits": "2.0.3", 377 | "setprototypeof": "1.0.3", 378 | "statuses": ">= 1.3.1 < 2" 379 | } 380 | }, 381 | "setprototypeof": { 382 | "version": "1.0.3", 383 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 384 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", 385 | "dev": true 386 | } 387 | } 388 | }, 389 | "safe-buffer": { 390 | "version": "5.1.1", 391 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 392 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", 393 | "dev": true 394 | }, 395 | "send": { 396 | "version": "0.16.2", 397 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", 398 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", 399 | "dev": true, 400 | "requires": { 401 | "debug": "2.6.9", 402 | "depd": "~1.1.2", 403 | "destroy": "~1.0.4", 404 | "encodeurl": "~1.0.2", 405 | "escape-html": "~1.0.3", 406 | "etag": "~1.8.1", 407 | "fresh": "0.5.2", 408 | "http-errors": "~1.6.2", 409 | "mime": "1.4.1", 410 | "ms": "2.0.0", 411 | "on-finished": "~2.3.0", 412 | "range-parser": "~1.2.0", 413 | "statuses": "~1.4.0" 414 | } 415 | }, 416 | "serve-static": { 417 | "version": "1.13.2", 418 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", 419 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", 420 | "dev": true, 421 | "requires": { 422 | "encodeurl": "~1.0.2", 423 | "escape-html": "~1.0.3", 424 | "parseurl": "~1.3.2", 425 | "send": "0.16.2" 426 | } 427 | }, 428 | "setprototypeof": { 429 | "version": "1.1.0", 430 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 431 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", 432 | "dev": true 433 | }, 434 | "statuses": { 435 | "version": "1.4.0", 436 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 437 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", 438 | "dev": true 439 | }, 440 | "type-is": { 441 | "version": "1.6.16", 442 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", 443 | "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", 444 | "dev": true, 445 | "requires": { 446 | "media-typer": "0.3.0", 447 | "mime-types": "~2.1.18" 448 | } 449 | }, 450 | "unpipe": { 451 | "version": "1.0.0", 452 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 453 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 454 | "dev": true 455 | }, 456 | "utils-merge": { 457 | "version": "1.0.1", 458 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 459 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 460 | "dev": true 461 | }, 462 | "vary": { 463 | "version": "1.1.2", 464 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 465 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 466 | "dev": true 467 | } 468 | } 469 | } 470 | -------------------------------------------------------------------------------- /跨域问题/iframe+window.name/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "window.name", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "devDependencies": { 7 | "express": "^4.16.3" 8 | }, 9 | "dependencies": { 10 | "axios": "^1.6.5" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /跨域问题/iframe+window.name/server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | 4 | // 定义路由 5 | 6 | var router = express.Router(); 7 | 8 | router.get('/api/get',function(req,res){ 9 | res.send(``); 12 | }) 13 | 14 | app.use(router); 15 | 16 | var port = process.env.PORT || 8383; 17 | 18 | app.listen(port); 19 | 20 | console.log('Magic happens on port' + port); -------------------------------------------------------------------------------- /跨域问题/iframe+window.name/yarn-error.log: -------------------------------------------------------------------------------- 1 | Arguments: 2 | C:\Program Files\nodejs\node.exe C:\Program Files (x86)\Yarn\bin\yarn.js add express 3 | 4 | PATH: 5 | C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Users\Administrator\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\nodejs;C:\Program Files\Git\cmd;C:\Program Files (x86)\Yarn\bin;C:\Program Files\Microsoft VS Code\bin;C:\Users\Administrator\AppData\Roaming\npm;C:\Users\Administrator\AppData\Local\Yarn\bin 6 | 7 | Yarn version: 8 | 1.7.0 9 | 10 | Node version: 11 | 10.5.0 12 | 13 | Platform: 14 | win32 x64 15 | 16 | Trace: 17 | Error: connect ETIMEDOUT 104.18.94.96:443 18 | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:14) 19 | 20 | npm manifest: 21 | { 22 | "name": "window.name", 23 | "version": "1.0.0", 24 | "main": "index.js", 25 | "license": "MIT" 26 | } 27 | 28 | yarn manifest: 29 | No manifest 30 | 31 | Lockfile: 32 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 33 | # yarn lockfile v1 34 | -------------------------------------------------------------------------------- /跨域问题/iframe+window.name/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | accepts@~1.3.7: 6 | version "1.3.7" 7 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" 8 | dependencies: 9 | mime-types "~2.1.24" 10 | negotiator "0.6.2" 11 | 12 | array-flatten@1.1.1: 13 | version "1.1.1" 14 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 15 | 16 | asynckit@^0.4.0: 17 | version "0.4.0" 18 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 19 | 20 | axios@^1.6.5: 21 | version "1.6.5" 22 | resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.5.tgz#2c090da14aeeab3770ad30c3a1461bc970fb0cd8" 23 | dependencies: 24 | follow-redirects "^1.15.4" 25 | form-data "^4.0.0" 26 | proxy-from-env "^1.1.0" 27 | 28 | body-parser@1.19.0: 29 | version "1.19.0" 30 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" 31 | dependencies: 32 | bytes "3.1.0" 33 | content-type "~1.0.4" 34 | debug "2.6.9" 35 | depd "~1.1.2" 36 | http-errors "1.7.2" 37 | iconv-lite "0.4.24" 38 | on-finished "~2.3.0" 39 | qs "6.7.0" 40 | raw-body "2.4.0" 41 | type-is "~1.6.17" 42 | 43 | bytes@3.1.0: 44 | version "3.1.0" 45 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" 46 | 47 | combined-stream@^1.0.8: 48 | version "1.0.8" 49 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 50 | dependencies: 51 | delayed-stream "~1.0.0" 52 | 53 | content-disposition@0.5.3: 54 | version "0.5.3" 55 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" 56 | dependencies: 57 | safe-buffer "5.1.2" 58 | 59 | content-type@~1.0.4: 60 | version "1.0.4" 61 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 62 | 63 | cookie-signature@1.0.6: 64 | version "1.0.6" 65 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 66 | 67 | cookie@0.4.0: 68 | version "0.4.0" 69 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" 70 | 71 | debug@2.6.9: 72 | version "2.6.9" 73 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 74 | dependencies: 75 | ms "2.0.0" 76 | 77 | delayed-stream@~1.0.0: 78 | version "1.0.0" 79 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 80 | 81 | depd@~1.1.2: 82 | version "1.1.2" 83 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 84 | 85 | destroy@~1.0.4: 86 | version "1.0.4" 87 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 88 | 89 | ee-first@1.1.1: 90 | version "1.1.1" 91 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 92 | 93 | encodeurl@~1.0.2: 94 | version "1.0.2" 95 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 96 | 97 | escape-html@~1.0.3: 98 | version "1.0.3" 99 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 100 | 101 | etag@~1.8.1: 102 | version "1.8.1" 103 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 104 | 105 | express@^4.16.3: 106 | version "4.17.1" 107 | resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" 108 | dependencies: 109 | accepts "~1.3.7" 110 | array-flatten "1.1.1" 111 | body-parser "1.19.0" 112 | content-disposition "0.5.3" 113 | content-type "~1.0.4" 114 | cookie "0.4.0" 115 | cookie-signature "1.0.6" 116 | debug "2.6.9" 117 | depd "~1.1.2" 118 | encodeurl "~1.0.2" 119 | escape-html "~1.0.3" 120 | etag "~1.8.1" 121 | finalhandler "~1.1.2" 122 | fresh "0.5.2" 123 | merge-descriptors "1.0.1" 124 | methods "~1.1.2" 125 | on-finished "~2.3.0" 126 | parseurl "~1.3.3" 127 | path-to-regexp "0.1.7" 128 | proxy-addr "~2.0.5" 129 | qs "6.7.0" 130 | range-parser "~1.2.1" 131 | safe-buffer "5.1.2" 132 | send "0.17.1" 133 | serve-static "1.14.1" 134 | setprototypeof "1.1.1" 135 | statuses "~1.5.0" 136 | type-is "~1.6.18" 137 | utils-merge "1.0.1" 138 | vary "~1.1.2" 139 | 140 | finalhandler@~1.1.2: 141 | version "1.1.2" 142 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" 143 | dependencies: 144 | debug "2.6.9" 145 | encodeurl "~1.0.2" 146 | escape-html "~1.0.3" 147 | on-finished "~2.3.0" 148 | parseurl "~1.3.3" 149 | statuses "~1.5.0" 150 | unpipe "~1.0.0" 151 | 152 | follow-redirects@^1.15.4: 153 | version "1.15.4" 154 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" 155 | 156 | form-data@^4.0.0: 157 | version "4.0.0" 158 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" 159 | dependencies: 160 | asynckit "^0.4.0" 161 | combined-stream "^1.0.8" 162 | mime-types "^2.1.12" 163 | 164 | forwarded@~0.1.2: 165 | version "0.1.2" 166 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" 167 | 168 | fresh@0.5.2: 169 | version "0.5.2" 170 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 171 | 172 | http-errors@1.7.2: 173 | version "1.7.2" 174 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" 175 | dependencies: 176 | depd "~1.1.2" 177 | inherits "2.0.3" 178 | setprototypeof "1.1.1" 179 | statuses ">= 1.5.0 < 2" 180 | toidentifier "1.0.0" 181 | 182 | http-errors@~1.7.2: 183 | version "1.7.3" 184 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" 185 | dependencies: 186 | depd "~1.1.2" 187 | inherits "2.0.4" 188 | setprototypeof "1.1.1" 189 | statuses ">= 1.5.0 < 2" 190 | toidentifier "1.0.0" 191 | 192 | iconv-lite@0.4.24: 193 | version "0.4.24" 194 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 195 | dependencies: 196 | safer-buffer ">= 2.1.2 < 3" 197 | 198 | inherits@2.0.3: 199 | version "2.0.3" 200 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 201 | 202 | inherits@2.0.4: 203 | version "2.0.4" 204 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 205 | 206 | ipaddr.js@1.9.0: 207 | version "1.9.0" 208 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" 209 | 210 | media-typer@0.3.0: 211 | version "0.3.0" 212 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 213 | 214 | merge-descriptors@1.0.1: 215 | version "1.0.1" 216 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 217 | 218 | methods@~1.1.2: 219 | version "1.1.2" 220 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 221 | 222 | mime-db@1.40.0: 223 | version "1.40.0" 224 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" 225 | 226 | mime-db@1.52.0: 227 | version "1.52.0" 228 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 229 | 230 | mime-types@^2.1.12: 231 | version "2.1.35" 232 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 233 | dependencies: 234 | mime-db "1.52.0" 235 | 236 | mime-types@~2.1.24: 237 | version "2.1.24" 238 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" 239 | dependencies: 240 | mime-db "1.40.0" 241 | 242 | mime@1.6.0: 243 | version "1.6.0" 244 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 245 | 246 | ms@2.0.0: 247 | version "2.0.0" 248 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 249 | 250 | ms@2.1.1: 251 | version "2.1.1" 252 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 253 | 254 | negotiator@0.6.2: 255 | version "0.6.2" 256 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" 257 | 258 | on-finished@~2.3.0: 259 | version "2.3.0" 260 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 261 | dependencies: 262 | ee-first "1.1.1" 263 | 264 | parseurl@~1.3.3: 265 | version "1.3.3" 266 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" 267 | 268 | path-to-regexp@0.1.7: 269 | version "0.1.7" 270 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 271 | 272 | proxy-addr@~2.0.5: 273 | version "2.0.5" 274 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" 275 | dependencies: 276 | forwarded "~0.1.2" 277 | ipaddr.js "1.9.0" 278 | 279 | proxy-from-env@^1.1.0: 280 | version "1.1.0" 281 | resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" 282 | 283 | qs@6.7.0: 284 | version "6.7.0" 285 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" 286 | 287 | range-parser@~1.2.1: 288 | version "1.2.1" 289 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" 290 | 291 | raw-body@2.4.0: 292 | version "2.4.0" 293 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" 294 | dependencies: 295 | bytes "3.1.0" 296 | http-errors "1.7.2" 297 | iconv-lite "0.4.24" 298 | unpipe "1.0.0" 299 | 300 | safe-buffer@5.1.2: 301 | version "5.1.2" 302 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 303 | 304 | "safer-buffer@>= 2.1.2 < 3": 305 | version "2.1.2" 306 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 307 | 308 | send@0.17.1: 309 | version "0.17.1" 310 | resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" 311 | dependencies: 312 | debug "2.6.9" 313 | depd "~1.1.2" 314 | destroy "~1.0.4" 315 | encodeurl "~1.0.2" 316 | escape-html "~1.0.3" 317 | etag "~1.8.1" 318 | fresh "0.5.2" 319 | http-errors "~1.7.2" 320 | mime "1.6.0" 321 | ms "2.1.1" 322 | on-finished "~2.3.0" 323 | range-parser "~1.2.1" 324 | statuses "~1.5.0" 325 | 326 | serve-static@1.14.1: 327 | version "1.14.1" 328 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" 329 | dependencies: 330 | encodeurl "~1.0.2" 331 | escape-html "~1.0.3" 332 | parseurl "~1.3.3" 333 | send "0.17.1" 334 | 335 | setprototypeof@1.1.1: 336 | version "1.1.1" 337 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" 338 | 339 | "statuses@>= 1.5.0 < 2", statuses@~1.5.0: 340 | version "1.5.0" 341 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 342 | 343 | toidentifier@1.0.0: 344 | version "1.0.0" 345 | resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" 346 | 347 | type-is@~1.6.17, type-is@~1.6.18: 348 | version "1.6.18" 349 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" 350 | dependencies: 351 | media-typer "0.3.0" 352 | mime-types "~2.1.24" 353 | 354 | unpipe@1.0.0, unpipe@~1.0.0: 355 | version "1.0.0" 356 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 357 | 358 | utils-merge@1.0.1: 359 | version "1.0.1" 360 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 361 | 362 | vary@~1.1.2: 363 | version "1.1.2" 364 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 365 | -------------------------------------------------------------------------------- /跨域问题/jsonp/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /跨域问题/jsonp/server/data.js: -------------------------------------------------------------------------------- 1 | // 不在同一域名的js 请使用http-server 启动一个服务 8081 2 | // 数据 3 | const data = { 4 | list:[ 5 | { 6 | name:"data1", 7 | someOther:{} 8 | }, 9 | { 10 | name:"data2", 11 | someOther:{} 12 | }, 13 | { 14 | name:"data3", 15 | someOther:{} 16 | } 17 | ] 18 | } 19 | 20 | //调用 8080 下的 函数 21 | callBack(data); // 调用callback 函数传递数据 // callback目前是未定义的 但是index里面会定义好 22 | --------------------------------------------------------------------------------