@Bios
2019-06-28T06:50:15.000000Z
字数 11858
阅读 965
前端 js
CORS TM的就是 Access-Control-Allow-Origin 主要还是靠服务器端来实现,
ajax2.0 中有了一个formData,要靠这个来传参。ajax2.0比ajax1.0多了一个 origin,表示请求源,后台可以通过 req.header拿到,拿到这个,就可以判断 是否允许这个 origin 跨域,也就是设置Access-Control-Allow-Origin
const http=require('http');let allowHosts=['baidu.com', 'taobao.com', 'tmall.com', 'google.com'];let server=http.createServer(function (req, res){if(allowHosts.indexOf(req.headers['origin'])!=-1){res.setHeader('Access-Control-Allow-Origin', '*');}res.write('abc');res.end();});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。
window.onload=function (){var oBtn=document.getElementById('btn1');oBtn.onclick=function (){var formData=new FormData();formData.set('a', 12);var xhr=new XMLHttpRequest();xhr.open('post', '1.php', true);xhr.send(formData);xhr.onreadystatechange=function (){if(xhr.readyState==4){ //?if((xhr.status>=200 && xhr.status<300) || xhr.status==304){alert(xhr.responseText);}else{alert('错了');}}};};};
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
上传文件:
<input type="file" id="f1"><input type="button" value="ajax请求" id="btn1">window.onload=function (){var oBtn=document.getElementById('btn1');var oF1=document.getElementById('f1');oBtn.onclick=function (){var formData=new FormData();formData.set('f1', oF1);var xhr=new XMLHttpRequest();xhr.upload.onload=function (){console.log('上传完成');};xhr.upload.onprogress=function (ev){console.log(ev.loaded, ev.total);};xhr.open('post', '2.php', true);xhr.send(formData);xhr.onreadystatechange=function (){if(xhr.readyState==4){ //?alert(xhr.status);}};};};
创建一个script标签,给一个src,回调一个函数
百度搜索
<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><script>function show(json){let oUl=document.getElementById('ul1');oUl.innerHTML='';json.s.forEach(str=>{let oLi=document.createElement('li');oLi.innerHTML=str;oUl.appendChild(oLi);});}</script><!--<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=acc&cb=show" charset="utf-8"></script>--><script>window.onload=function (){let oTxt=document.getElementById('txt1');let oUl=document.getElementById('ul1');oTxt.oninput=function (){let oS=document.createElement('script');oS.src=`https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=${oTxt.value}&cb=show`;document.head.appendChild(oS);};};</script></head><body><input type="text" id="txt1"><ul id="ul1"></ul></body></html>
<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><script src="jquery.js" charset="utf-8"></script><script>$(function (){$('#txt1').on('input', function (){$.ajax({url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',data: {wd: $('#txt1').val()},dataType: 'jsonp',jsonp: 'cb', // 百度的回调是cbsuccess(json){$('#ul1').html('');json.s.forEach(str=>{$(`<li>${str}</li>`).appendTo('#ul1');});},error(){alert('错了');}});});});</script></head><body><input type="text" id="txt1"><ul id="ul1"></ul></body></html>
服务器端怎么写jsonp接口
const http=require('http');const url=require('url');let server=http.createServer(function (req, res){let {pathname, query}=url.parse(req.url, true);let {a,b,callback}=query;res.write(`${callback}(${parseInt(a)+parseInt(b)})`);res.end();});server.listen(8080);
window.navigator.geolocation单次 getCurrentPosition(成功, 失败, 参数)enableHighAccuracy 高精度模式——更慢、更费电timeout 超时maximumAge 缓存时间结果:latitude/longitude 纬度/经度altitude 海拔高度accuracy 精确度altitudeAccuracy 高度精确度heading 朝向speed 速度监听 watchPosition(成功, 失败, 参数)
window.onload=function (){let oBtn=document.getElementById('btn1');oBtn.onclick=function (){if(window.navigator.geolocation){navigator.geolocation.getCurrentPosition(res=>{alert('成功');}, err=>{alert('失败');}, {/*enableHighAccuracy //高精度模式timeout //超时时间maximumAge //缓存*/});}else{alert('你的浏览器不支持定位');}};};
video、audiovideo——视频src 地址autoplay 自动播放loop 循环播放poster 封面地址如果不支持video就加载flash<video><flash></flash></video>video支持什么格式——通用格式mp4IE wmv、mp4Chrome webq、mp4FireFox ogv、mp4audio——mp3JS接口.play() 播放.pause() 暂停.stop() ×pause+currentTime.currentTime 当前播放位置(s).duration 长度(s).volume 音量:0-100.muted 静音:bool播放速度怎么设置1.服务调整,存成多个文件2.点播调整码率video宽高怎么适配到div宽600, height400在容器内,并且视频不能变畸形W=600H=400w,hif(w/h>W/H){ //“偏宽一些”//让宽度适应容器宽度h=H*w/Ww=W}else{ //“偏高一些”h=Hw=W*h/H}试看5分钟或者试听5分钟怎么做?不能用客户端实现(可以直接禁用javascript,写的再高深也没用)服务器怎么干掉 video / audio 里 自带control 的下载按钮?流视频
主机 > 程序 > 进程 > 线程 > 纤程多进程(重) 多线程(轻)开销 创建、销毁开销大 创建、销毁开销小安全性 进程之间是隔离 线程之间是共享资源 每个进程独立资源 同一个进程的所有线程共享资源共享资源 麻烦 方便编程难度 低(资源是独享的) 高(资源是共享的)总结:多进程:性能低、编写简单多线程:性能高、编写复杂Java、c 多进程/多线程PHP 多进程JS 多进程WebWorker——浏览器上实现的多进程Web端:主进程 UI进程子进程(工作进程) 看不见的;只能完成计算、数据请求这些操作优点:1.充分利用资源(多个进程同时工作)2.防止主进程卡住缺点:不能执行任何UI操作,子进程只能执行计算型任务结论:WebWorker在工作中用的很少——Web中计算型任务就不多
<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><script>window.onload=function (){let oBtn=document.getElementById('btn1');let oTxt1=document.getElementById('txt1');let oTxt2=document.getElementById('txt2');oBtn.onclick=function (){let n1=parseInt(oTxt1.value);let n2=parseInt(oTxt2.value);//1.创建子进程let w=new Worker('w1.js');//2.发送w.postMessage({n1, n2});//6.接收结果w.onmessage=function (ev){alert(ev.data);};};};</script></head><body><input type="text" id="txt1"><input type="text" id="txt2"><input type="button" value="计算" id="btn1"></body></html>
// w1.js//3.接收this.onmessage=function (ev){//console.log('我得到了:', ev.data);//4.处理任务let sum=ev.data.n1+ev.data.n2;//5.返回this.postMessage(sum);};
<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><style media="screen">#div1 {width:400px; height:200px; background:#CCC; border:1px solid black; margin:50px auto 0; text-align:center; line-height:200px;}</style><script>window.onload=function (){let oDiv=document.getElementById('div1');//ondragenter 进入//ondragleave 离开//ondragover 悬停——只要没走,就一直发生//ondrop 松开鼠标——如果dragover不阻止默认事件,drop压根不会发生oDiv.addEventListener('dragenter', function (){oDiv.innerHTML='释放鼠标';}, false);oDiv.addEventListener('dragleave', function (){oDiv.innerHTML='将文件拖拽至此区域';}, false);//只要没离开——一直发生oDiv.addEventListener('dragover', function (ev){console.log('dragover');ev.preventDefault();}, false);oDiv.addEventListener('drop', function (ev){console.log(ev.dataTransfer.files);console.log('drop');ev.preventDefault();}, false);};</script></head><body><div id="div1">将文件拖拽至此区域</div></body></html>
document.querySelector("选择器") 符合条件的第一个document.querySelectorAll("选择器") 符合条件的全部DOM.classList.add('类名')DOM.classList.remove('类名')DOM.classList.contains('类名')DOM.classList.toggle('类名')自定义属性:data-自定义属性名,例如:data-index="1" data-name-age="hahha" (dataset.nameAge 驼峰命名获取)DOM.dataset 返回一个对象,来获取自定义属性值
事件:FileReader.onabort处理abort事件。该事件在读取操作被中断时触发。FileReader.onerror处理error事件。该事件在读取操作发生错误时触发。FileReader.onload处理load事件。该事件在读取操作完成时触发。FileReader.onloadstart处理loadstart事件。该事件在读取操作开始时触发。FileReader.onloadend处理loadend事件。该事件在读取操作结束时(要么成功,要么失败)触发。FileReader.onprogress处理progress事件。该事件在读取Blob时触发。方法:FileReader.abort()中止读取操作。在返回时,readyState属性为DONE。FileReader.readAsArrayBuffer() `(原始二进制数据)`开始读取指定的 Blob中的内容, 一旦完成, result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象.FileReader.readAsBinaryString() `(二进制的文本形式数据)`开始读取指定的Blob中的内容。一旦完成,result属性中将包含所读取文件的原始二进制数据。FileReader.readAsDataURL() `(base64)`开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容。FileReader.readAsText() `(文本)`开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个字符串以表示所读取的文件内容。reader.readAsText(oFile) 文本 文本文件reader.readAsDataURL(oFile) base64 图片reader.readAsArrayBuffer(oFile) 原始二进制数据 编辑 不实用reader.readAsBinaryString(oFile) 二进制的文本形式数据 上传
拖拽图片转base64预览:
<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><style media="screen">#div1 {width:400px; height:300px; background:#CCC; border:1px solid black; text-align:center; line-height:300px;}</style><script>window.onload=function (){let oDiv=document.getElementById('div1');let oImg=document.getElementById('img1');oDiv.addEventListener('dragenter', function (){oDiv.innerHTML='请松手';}, false);oDiv.addEventListener('dragleave', function (){oDiv.innerHTML='拖到这里上传';}, false);oDiv.addEventListener('dragover', function (ev){ev.preventDefault();}, false);oDiv.addEventListener('drop', function (ev){ev.preventDefault();//let oFile=ev.dataTransfer.files[0];//读取let reader=new FileReader();reader.readAsDataURL(oFile);reader.onload=function (){//alert('成功');oImg.src=this.result;};reader.onerror=function (){alert('读取失败了');};console.log(reader);}, false);}</script></head><body><div id="div1">拖到这里上传</div><img src="" id="img1"></body></html>
获取当前网络状态:window.navigator.onLine 返回一个布尔值网络状态事件:window.ononlinewindow.onoffline
canvas——画布
1.什么东西都能画
2.性能特别高——大型动画、游戏
没有基础哈,适合有vue项目经验的人看!
yarn add @vue/cli-service-global -g vue单文件运行插件。
然后新建一个单独的vue项目,vue serve xxx.vue就可以在浏览器打开了(http://localhost:8080/)。
我们可以知道,v-model是v-bind以及v-on配合使用的语法糖,给一个详细的例子:
<input v-model="value" /><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 选项可以回避这些情况产生的冲突。
// 父组件<template><div id="app"><div class="left">父组件展示checked选中:{{checked}}</div><p>子组件:</p><radio class="right" :options="options" v-model="checked"></radio></div></template><script>import radio from '@/components/radio.vue'export default {name: 'App',components: {radio},data() {return {checked: 0,options: [{value: 0,name: '选项1'}, {value: 1,name: '选项2'}]}},// 父组件的改变 自组件也会响应mounted() {let _this = thissetInterval(function(){// console.log(1)_this.checked = _this.checked==0?1:0console.log(_this.checked)},1000)},}</script>
// 自组件<template><div class="radio"><div class="radioGroup"><divclass="radioItem"v-for="item in options":key="item.value"@click="clickRadio(item.value);"><divclass="radioBox":class="{ checked: item.value === checked }"></div><div class="name">{{ item.name }}</div></div></div></div></template><script>export default {name: "radio",props: {options: Array,value: Number},computed: {checked: {get() {return this.value;},set() {}}},model: {prop: "value", //绑定的值,通过父组件传递 这个和props中的value对应 也就是 v-bind:[value]event: "update" //自定义事件名 这个事件必须定义 不派发事件,或者不定义这个event父组件都拿不到值 也就是 v-on:[update]},methods: {clickRadio(val) {debuggerthis.checked = val;this.$emit("update", val); //子组件与父组件通讯,告知父组件更新绑定的值}},watch: {checked: function(newVal, oldVal) {console.log("我是子组件,现在的值为:" + newVal);// alert("我是子组件,现在的值为:" + newVal);}}};</script><style>.radioItem{display: flex;justify-content: center;}.radioBox {width: 20px;height: 20px;border-radius: 50%;border: 1px solid;}.checked{height: 20px;background: #ff0000;}</style>
// vue.config.jsmodule.exports = {configureWebpack: {devServer: {before(app) {app.get('/api/goods', (req, res) => {res.json({code: 0,list: [{id:1,name:'苹果'},{id:2,name:'香蕉'}]})})}}}}
// 请求数据axios.get('/api/goods').then(res => {})
// vue.config.jsmodule.exports = {configureWebpack: {devServer: {proxy: {'/api': {target: 'http://localhost:8080',changeOrigin: true,pathRewrite: {'^/api': '/mock'}}}}}}
新建mock数据: public/mock/member.json
[{"id":0,"name":"finget","age":23},{"id":1,"name":"finget1","age":23},{"id":2,"name":"finget2","age":23},{"id":3,"name":"finget3","age":23}]
axios.get('/api/member.json').then(res => {})
// plugins/element.jsimport Vue from 'vue';import { Button, Select } from 'element-ui';Vue.use(Button);Vue.use(Select);// main.jsimport './plugins/element.js'
provide和inject主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。
// 父级组件提供 'foo'var Provider = {provide: {foo: 'bar'},// ...}// 子组件注入 'foo'var Child = {inject: ['foo'],created () {console.log(this.foo) // => "bar"}// ...}
提示:
provide和inject绑定并不是可响应的。