@Bios
2019-06-28T06:50:15.000000Z
字数 11858
阅读 864
前端
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', // 百度的回调是cb
success(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、audio
video——视频
src 地址
autoplay 自动播放
loop 循环播放
poster 封面地址
如果不支持video就加载flash
<video><flash></flash></video>
video支持什么格式——通用格式mp4
IE wmv、mp4
Chrome webq、mp4
FireFox ogv、mp4
audio——mp3
JS接口
.play() 播放
.pause() 暂停
.stop() ×
pause+currentTime
.currentTime 当前播放位置(s)
.duration 长度(s)
.volume 音量:0-100
.muted 静音:bool
播放速度怎么设置
1.服务调整,存成多个文件
2.点播调整码率
video宽高怎么适配到div宽600, height400在容器内,并且视频不能变畸形
W=600
H=400
w,h
if(w/h>W/H){ //“偏宽一些”
//让宽度适应容器宽度
h=H*w/W
w=W
}else{ //“偏高一些”
h=H
w=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.ononline
window.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 = this
setInterval(function(){
// console.log(1)
_this.checked = _this.checked==0?1:0
console.log(_this.checked)
},1000)
},
}
</script>
// 自组件
<template>
<div class="radio">
<div class="radioGroup">
<div
class="radioItem"
v-for="item in options"
:key="item.value"
@click="clickRadio(item.value);"
>
<div
class="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) {
debugger
this.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.js
module.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.js
module.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.js
import Vue from 'vue';
import { Button, Select } from 'element-ui';
Vue.use(Button);
Vue.use(Select);
// main.js
import './plugins/element.js'
provide
和inject
主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
// ...
}
// 子组件注入 'foo'
var Child = {
inject: ['foo'],
created () {
console.log(this.foo) // => "bar"
}
// ...
}
提示:
provide
和inject
绑定并不是可响应的。