[关闭]
@Bios 2019-06-28T06:50:15.000000Z 字数 11858 阅读 766

WEB全栈学习笔记(乱记)

前端 js


ajax2.0

CORS TM的就是 Access-Control-Allow-Origin 主要还是靠服务器端来实现,

ajax2.0 中有了一个formData,要靠这个来传参。ajax2.0比ajax1.0多了一个 origin,表示请求源,后台可以通过 req.header拿到,拿到这个,就可以判断 是否允许这个 origin 跨域,也就是设置Access-Control-Allow-Origin

  1. const http=require('http');
  2. let allowHosts=['baidu.com', 'taobao.com', 'tmall.com', 'google.com'];
  3. let server=http.createServer(function (req, res){
  4. if(allowHosts.indexOf(req.headers['origin'])!=-1){
  5. res.setHeader('Access-Control-Allow-Origin', '*');
  6. }
  7. res.write('abc');
  8. res.end();
  9. });
  10. server.listen(8080);

let hxr = new XMLHttpRequest() 现在主流浏览器发起的ajax请求都是ajax2.0

hxr.upload 监听文件上传

upload:XMLHttpRequestUpload
onabort:null
onerror:null
onload:null // 上传完成
onloadend:null
onloadstart:null
onprogress:null // 上传进度
ontimeout:null

formData.set('a', file) 这个file就是通过input file 获取的文件,multipart/form-data就是上次文件用的。

application/x-www-form-urlencoded:数据被编码为名称/值对。这是标准的编码格式。
multipart/form-data: 数据被编码为一条消息,页上的每个控件对应消息中的一个部分。
text/plain: 数据以纯文本形式(text/json/xml/html)进行编码,其中不含任何控件或格式字符。postman软件里标的是RAW。

  1. window.onload=function (){
  2. var oBtn=document.getElementById('btn1');
  3. oBtn.onclick=function (){
  4. var formData=new FormData();
  5. formData.set('a', 12);
  6. var xhr=new XMLHttpRequest();
  7. xhr.open('post', '1.php', true);
  8. xhr.send(formData);
  9. xhr.onreadystatechange=function (){
  10. if(xhr.readyState==4){ //?
  11. if((xhr.status>=200 && xhr.status<300) || xhr.status==304){
  12. alert(xhr.responseText);
  13. }else{
  14. alert('错了');
  15. }
  16. }
  17. };
  18. };
  19. };

FormData {}
proto:FormData
append:ƒ append()
delete:ƒ delete()
entries:ƒ entries()
forEach:ƒ forEach()
get:ƒ ()
getAll:ƒ getAll()
has:ƒ has()
keys:ƒ keys()
set:ƒ ()
values:ƒ values()
constructor:ƒ FormData()
Symbol(Symbol.iterator):ƒ entries()
Symbol(Symbol.toStringTag):"FormData"
proto:Object

上传文件:

  1. <input type="file" id="f1">
  2. <input type="button" value="ajax请求" id="btn1">
  3. window.onload=function (){
  4. var oBtn=document.getElementById('btn1');
  5. var oF1=document.getElementById('f1');
  6. oBtn.onclick=function (){
  7. var formData=new FormData();
  8. formData.set('f1', oF1);
  9. var xhr=new XMLHttpRequest();
  10. xhr.upload.onload=function (){
  11. console.log('上传完成');
  12. };
  13. xhr.upload.onprogress=function (ev){
  14. console.log(ev.loaded, ev.total);
  15. };
  16. xhr.open('post', '2.php', true);
  17. xhr.send(formData);
  18. xhr.onreadystatechange=function (){
  19. if(xhr.readyState==4){ //?
  20. alert(xhr.status);
  21. }
  22. };
  23. };
  24. };

跨域资源共享 CORS 详解

JSONP

创建一个script标签,给一个src,回调一个函数

百度搜索

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <script>
  7. function show(json){
  8. let oUl=document.getElementById('ul1');
  9. oUl.innerHTML='';
  10. json.s.forEach(str=>{
  11. let oLi=document.createElement('li');
  12. oLi.innerHTML=str;
  13. oUl.appendChild(oLi);
  14. });
  15. }
  16. </script>
  17. <!--<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=acc&cb=show" charset="utf-8"></script>-->
  18. <script>
  19. window.onload=function (){
  20. let oTxt=document.getElementById('txt1');
  21. let oUl=document.getElementById('ul1');
  22. oTxt.oninput=function (){
  23. let oS=document.createElement('script');
  24. oS.src=`https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=${oTxt.value}&cb=show`;
  25. document.head.appendChild(oS);
  26. };
  27. };
  28. </script>
  29. </head>
  30. <body>
  31. <input type="text" id="txt1">
  32. <ul id="ul1"></ul>
  33. </body>
  34. </html>
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <script src="jquery.js" charset="utf-8"></script>
  7. <script>
  8. $(function (){
  9. $('#txt1').on('input', function (){
  10. $.ajax({
  11. url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',
  12. data: {wd: $('#txt1').val()},
  13. dataType: 'jsonp',
  14. jsonp: 'cb', // 百度的回调是cb
  15. success(json){
  16. $('#ul1').html('');
  17. json.s.forEach(str=>{
  18. $(`<li>${str}</li>`).appendTo('#ul1');
  19. });
  20. },
  21. error(){
  22. alert('错了');
  23. }
  24. });
  25. });
  26. });
  27. </script>
  28. </head>
  29. <body>
  30. <input type="text" id="txt1">
  31. <ul id="ul1"></ul>
  32. </body>
  33. </html>

服务器端怎么写jsonp接口

  1. const http=require('http');
  2. const url=require('url');
  3. let server=http.createServer(function (req, res){
  4. let {pathname, query}=url.parse(req.url, true);
  5. let {a,b,callback}=query;
  6. res.write(`${callback}(${parseInt(a)+parseInt(b)})`);
  7. res.end();
  8. });
  9. server.listen(8080);

H5

geolocation——定位

  1. window.navigator.geolocation
  2. 单次 getCurrentPosition(成功, 失败, 参数)
  3. enableHighAccuracy 高精度模式——更慢、更费电
  4. timeout 超时
  5. maximumAge 缓存时间
  6. 结果:
  7. latitude/longitude 纬度/经度
  8. altitude 海拔高度
  9. accuracy 精确度
  10. altitudeAccuracy 高度精确度
  11. heading 朝向
  12. speed 速度
  13. 监听 watchPosition(成功, 失败, 参数)
  1. window.onload=function (){
  2. let oBtn=document.getElementById('btn1');
  3. oBtn.onclick=function (){
  4. if(window.navigator.geolocation){
  5. navigator.geolocation.getCurrentPosition(res=>{
  6. alert('成功');
  7. }, err=>{
  8. alert('失败');
  9. }, {
  10. /*
  11. enableHighAccuracy //高精度模式
  12. timeout //超时时间
  13. maximumAge //缓存
  14. */
  15. });
  16. }else{
  17. alert('你的浏览器不支持定位');
  18. }
  19. };
  20. };

媒体播放

  1. videoaudio
  2. video——视频
  3. src 地址
  4. autoplay 自动播放
  5. loop 循环播放
  6. poster 封面地址
  7. 如果不支持video就加载flash
  8. <video><flash></flash></video>
  9. video支持什么格式——通用格式mp4
  10. IE wmvmp4
  11. Chrome webqmp4
  12. FireFox ogvmp4
  13. audio——mp3
  14. JS接口
  15. .play() 播放
  16. .pause() 暂停
  17. .stop() ×
  18. pause+currentTime
  19. .currentTime 当前播放位置(s)
  20. .duration 长度(s)
  21. .volume 音量:0-100
  22. .muted 静音:bool
  23. 播放速度怎么设置
  24. 1.服务调整,存成多个文件
  25. 2.点播调整码率
  26. video宽高怎么适配到div600, height400在容器内,并且视频不能变畸形
  27. W=600
  28. H=400
  29. w,h
  30. if(w/h>W/H){ //“偏宽一些”
  31. //让宽度适应容器宽度
  32. h=H*w/W
  33. w=W
  34. }else{ //“偏高一些”
  35. h=H
  36. w=W*h/H
  37. }
  38. 试看5分钟或者试听5分钟怎么做?
  39. 不能用客户端实现(可以直接禁用javascript,写的再高深也没用)
  40. 服务器
  41. 怎么干掉 video / audio 自带control 的下载按钮?
  42. 流视频

WebWorker

  1. 主机 > 程序 > 进程 > 线程 > 纤程
  2. 多进程(重) 多线程(轻)
  3. 开销 创建、销毁开销大 创建、销毁开销小
  4. 安全性 进程之间是隔离 线程之间是共享
  5. 资源 每个进程独立资源 同一个进程的所有线程共享资源
  6. 共享资源 麻烦 方便
  7. 编程难度 低(资源是独享的) 高(资源是共享的)
  8. 总结:
  9. 多进程:性能低、编写简单
  10. 多线程:性能高、编写复杂
  11. Javac 多进程/多线程
  12. PHP 多进程
  13. JS 多进程
  14. WebWorker——浏览器上实现的多进程
  15. Web端:
  16. 主进程 UI进程
  17. 子进程(工作进程) 看不见的;只能完成计算、数据请求这些操作
  18. 优点:
  19. 1.充分利用资源(多个进程同时工作)
  20. 2.防止主进程卡住
  21. 缺点:
  22. 不能执行任何UI操作,子进程只能执行计算型任务
  23. 结论:WebWorker在工作中用的很少——Web中计算型任务就不多
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <script>
  7. window.onload=function (){
  8. let oBtn=document.getElementById('btn1');
  9. let oTxt1=document.getElementById('txt1');
  10. let oTxt2=document.getElementById('txt2');
  11. oBtn.onclick=function (){
  12. let n1=parseInt(oTxt1.value);
  13. let n2=parseInt(oTxt2.value);
  14. //1.创建子进程
  15. let w=new Worker('w1.js');
  16. //2.发送
  17. w.postMessage({n1, n2});
  18. //6.接收结果
  19. w.onmessage=function (ev){
  20. alert(ev.data);
  21. };
  22. };
  23. };
  24. </script>
  25. </head>
  26. <body>
  27. <input type="text" id="txt1">
  28. <input type="text" id="txt2">
  29. <input type="button" value="计算" id="btn1">
  30. </body>
  31. </html>
  1. // w1.js
  2. //3.接收
  3. this.onmessage=function (ev){
  4. //console.log('我得到了:', ev.data);
  5. //4.处理任务
  6. let sum=ev.data.n1+ev.data.n2;
  7. //5.返回
  8. this.postMessage(sum);
  9. };

HTML5 Web Workers

文件拖拽

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <style media="screen">
  7. #div1 {width:400px; height:200px; background:#CCC; border:1px solid black; margin:50px auto 0; text-align:center; line-height:200px;}
  8. </style>
  9. <script>
  10. window.onload=function (){
  11. let oDiv=document.getElementById('div1');
  12. //ondragenter 进入
  13. //ondragleave 离开
  14. //ondragover 悬停——只要没走,就一直发生
  15. //ondrop 松开鼠标——如果dragover不阻止默认事件,drop压根不会发生
  16. oDiv.addEventListener('dragenter', function (){
  17. oDiv.innerHTML='释放鼠标';
  18. }, false);
  19. oDiv.addEventListener('dragleave', function (){
  20. oDiv.innerHTML='将文件拖拽至此区域';
  21. }, false);
  22. //只要没离开——一直发生
  23. oDiv.addEventListener('dragover', function (ev){
  24. console.log('dragover');
  25. ev.preventDefault();
  26. }, false);
  27. oDiv.addEventListener('drop', function (ev){
  28. console.log(ev.dataTransfer.files);
  29. console.log('drop');
  30. ev.preventDefault();
  31. }, false);
  32. };
  33. </script>
  34. </head>
  35. <body>
  36. <div id="div1">将文件拖拽至此区域</div>
  37. </body>
  38. </html>

获取页面元素及类名操作和自定义属性

  1. document.querySelector("选择器") 符合条件的第一个
  2. document.querySelectorAll("选择器") 符合条件的全部
  3. DOM.classList.add('类名')
  4. DOM.classList.remove('类名')
  5. DOM.classList.contains('类名')
  6. DOM.classList.toggle('类名')
  7. 自定义属性:
  8. data-自定义属性名,例如:data-index="1" data-name-age="hahha" (dataset.nameAge 驼峰命名获取)
  9. DOM.dataset 返回一个对象,来获取自定义属性值

FileReader

  1. 事件:
  2. FileReader.onabort
  3. 处理abort事件。该事件在读取操作被中断时触发。
  4. FileReader.onerror
  5. 处理error事件。该事件在读取操作发生错误时触发。
  6. FileReader.onload
  7. 处理load事件。该事件在读取操作完成时触发。
  8. FileReader.onloadstart
  9. 处理loadstart事件。该事件在读取操作开始时触发。
  10. FileReader.onloadend
  11. 处理loadend事件。该事件在读取操作结束时(要么成功,要么失败)触发。
  12. FileReader.onprogress
  13. 处理progress事件。该事件在读取Blob时触发。
  14. 方法:
  15. FileReader.abort()
  16. 中止读取操作。在返回时,readyState属性为DONE
  17. FileReader.readAsArrayBuffer() `(原始二进制数据)`
  18. 开始读取指定的 Blob中的内容, 一旦完成, result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象.
  19. FileReader.readAsBinaryString() `(二进制的文本形式数据)`
  20. 开始读取指定的Blob中的内容。一旦完成,result属性中将包含所读取文件的原始二进制数据。
  21. FileReader.readAsDataURL() `(base64)`
  22. 开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容。
  23. FileReader.readAsText() `(文本)`
  24. 开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个字符串以表示所读取的文件内容。
  25. reader.readAsText(oFile) 文本 文本文件
  26. reader.readAsDataURL(oFile) base64 图片
  27. reader.readAsArrayBuffer(oFile) 原始二进制数据 编辑 不实用
  28. reader.readAsBinaryString(oFile) 二进制的文本形式数据 上传

拖拽图片转base64预览:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. <style media="screen">
  7. #div1 {width:400px; height:300px; background:#CCC; border:1px solid black; text-align:center; line-height:300px;}
  8. </style>
  9. <script>
  10. window.onload=function (){
  11. let oDiv=document.getElementById('div1');
  12. let oImg=document.getElementById('img1');
  13. oDiv.addEventListener('dragenter', function (){
  14. oDiv.innerHTML='请松手';
  15. }, false);
  16. oDiv.addEventListener('dragleave', function (){
  17. oDiv.innerHTML='拖到这里上传';
  18. }, false);
  19. oDiv.addEventListener('dragover', function (ev){
  20. ev.preventDefault();
  21. }, false);
  22. oDiv.addEventListener('drop', function (ev){
  23. ev.preventDefault();
  24. //
  25. let oFile=ev.dataTransfer.files[0];
  26. //读取
  27. let reader=new FileReader();
  28. reader.readAsDataURL(oFile);
  29. reader.onload=function (){
  30. //alert('成功');
  31. oImg.src=this.result;
  32. };
  33. reader.onerror=function (){
  34. alert('读取失败了');
  35. };
  36. console.log(reader);
  37. }, false);
  38. }
  39. </script>
  40. </head>
  41. <body>
  42. <div id="div1">拖到这里上传</div>
  43. <img src="" id="img1">
  44. </body>
  45. </html>

获取网络状态

  1. 获取当前网络状态:
  2. window.navigator.onLine 返回一个布尔值
  3. 网络状态事件:
  4. window.ononline
  5. window.onoffline

canvas

canvas——画布
1.什么东西都能画
2.性能特别高——大型动画、游戏

web全栈架构师

vue

没有基础哈,适合有vue项目经验的人看!

如何运行单独的vue文件

yarn add @vue/cli-service-global -g vue单文件运行插件。

然后新建一个单独的vue项目,vue serve xxx.vue就可以在浏览器打开了(http://localhost:8080/)。

自定义组件上使用v-model

我们可以知道,v-model是v-bind以及v-on配合使用的语法糖,给一个详细的例子:

  1. <input v-model="value" />
  2. <input v-bind:value="value" v-on:input="value= $event.target.value" />

vue2.2+版本后,新增加了一个model选项,model选项允许自定义prop和event。官方原文是这样的:允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突。

  1. // 父组件
  2. <template>
  3. <div id="app">
  4. <div class="left">父组件展示checked选中:{{checked}}</div>
  5. <p>子组件:</p>
  6. <radio class="right" :options="options" v-model="checked"></radio>
  7. </div>
  8. </template>
  9. <script>
  10. import radio from '@/components/radio.vue'
  11. export default {
  12. name: 'App',
  13. components: {
  14. radio
  15. },
  16. data() {
  17. return {
  18. checked: 0,
  19. options: [{
  20. value: 0,
  21. name: '选项1'
  22. }, {
  23. value: 1,
  24. name: '选项2'
  25. }]
  26. }
  27. },
  28. // 父组件的改变 自组件也会响应
  29. mounted() {
  30. let _this = this
  31. setInterval(function(){
  32. // console.log(1)
  33. _this.checked = _this.checked==0?1:0
  34. console.log(_this.checked)
  35. },1000)
  36. },
  37. }
  38. </script>
  1. // 自组件
  2. <template>
  3. <div class="radio">
  4. <div class="radioGroup">
  5. <div
  6. class="radioItem"
  7. v-for="item in options"
  8. :key="item.value"
  9. @click="clickRadio(item.value);"
  10. >
  11. <div
  12. class="radioBox"
  13. :class="{ checked: item.value === checked }"
  14. ></div>
  15. <div class="name">{{ item.name }}</div>
  16. </div>
  17. </div>
  18. </div>
  19. </template>
  20. <script>
  21. export default {
  22. name: "radio",
  23. props: {
  24. options: Array,
  25. value: Number
  26. },
  27. computed: {
  28. checked: {
  29. get() {
  30. return this.value;
  31. },
  32. set() {}
  33. }
  34. },
  35. model: {
  36. prop: "value", //绑定的值,通过父组件传递 这个和props中的value对应 也就是 v-bind:[value]
  37. event: "update" //自定义事件名 这个事件必须定义 不派发事件,或者不定义这个event父组件都拿不到值 也就是 v-on:[update]
  38. },
  39. methods: {
  40. clickRadio(val) {
  41. debugger
  42. this.checked = val;
  43. this.$emit("update", val); //子组件与父组件通讯,告知父组件更新绑定的值
  44. }
  45. },
  46. watch: {
  47. checked: function(newVal, oldVal) {
  48. console.log("我是子组件,现在的值为:" + newVal);
  49. // alert("我是子组件,现在的值为:" + newVal);
  50. }
  51. }
  52. };
  53. </script>
  54. <style>
  55. .radioItem{
  56. display: flex;
  57. justify-content: center;
  58. }
  59. .radioBox {
  60. width: 20px;
  61. height: 20px;
  62. border-radius: 50%;
  63. border: 1px solid;
  64. }
  65. .checked{
  66. height: 20px;
  67. background: #ff0000;
  68. }
  69. </style>

vue-cli3 配置mock数据接口

  1. // vue.config.js
  2. module.exports = {
  3. configureWebpack: {
  4. devServer: {
  5. before(app) {
  6. app.get('/api/goods', (req, res) => {
  7. res.json({
  8. code: 0,
  9. list: [
  10. {id:1,name:'苹果'},
  11. {id:2,name:'香蕉'}
  12. ]
  13. })
  14. })
  15. }
  16. }
  17. }
  18. }
  1. // 请求数据
  2. axios.get('/api/goods').then(res => {})
  1. // vue.config.js
  2. module.exports = {
  3. configureWebpack: {
  4. devServer: {
  5. proxy: {
  6. '/api': {
  7. target: 'http://localhost:8080',
  8. changeOrigin: true,
  9. pathRewrite: {
  10. '^/api': '/mock'
  11. }
  12. }
  13. }
  14. }
  15. }
  16. }

新建mock数据: public/mock/member.json

  1. [
  2. {"id":0,"name":"finget","age":23},
  3. {"id":1,"name":"finget1","age":23},
  4. {"id":2,"name":"finget2","age":23},
  5. {"id":3,"name":"finget3","age":23}
  6. ]
  1. axios.get('/api/member.json').then(res => {})

组件分类

ElementUI按需加载

  1. // plugins/element.js
  2. import Vue from 'vue';
  3. import { Button, Select } from 'element-ui';
  4. Vue.use(Button);
  5. Vue.use(Select);
  6. // main.js
  7. import './plugins/element.js'

provide&inject

provideinject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。

  1. // 父级组件提供 'foo'
  2. var Provider = {
  3. provide: {
  4. foo: 'bar'
  5. },
  6. // ...
  7. }
  8. // 子组件注入 'foo'
  9. var Child = {
  10. inject: ['foo'],
  11. created () {
  12. console.log(this.foo) // => "bar"
  13. }
  14. // ...
  15. }

提示:provideinject 绑定并不是可响应的。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注