初级篇
js 中 module 的了解(概念性)
es6之前,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。ES6模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。有了静态分析就可以拓展js语法,引入宏(macro)和类型检验(type system)
es6模块还有以下好处:
- 遵循严格模式
- 不再需要UMD模块格式了,将来服务器和浏览器都会支持 ES6 模块格式。目前,通过各种工具库,其实已经做到了这一点。
- 将来浏览器的新 API 就能用模块格式提供,不再必须做成全局变量或者navigator对象的属性。
- 不再需要对象作为命名空间(比如Math对象)
一个module(模块)通常就是一个.js文件,通常模块内包含有封装好的方法,或者常量等。 es6的导出方式,分别是 export 和 export default. 普通导出(export)的模块,在导入时,通常eg:import{}。 默认导出(export default name)的模块,在导入时eg:import otherName 可以使用as来进行改名导出导入,eg:
export { area as circleArea } from 'circle';
import * as math from 'circleplus';
写一个单例模式
- 定义:只允许被实例化一次的类
- 应用:提供一个命名空间
- 代码:
let singleCase = function(name){
this.name = name;
};
singleCase.prototype.getName = function(){
return this.name;
}
// 获取实例对象
let getInstance = (function() {
let instance = null;
return function(name) {
if(!instance) {//相当于一个一次性阀门,只能实例化一次
instance = new singleCase(name);
}
return instance;
}
})();
// 测试单体模式的实例,所以one===two
let one = getInstance("one");
let two = getInstance("two");
console.log('one===two的结果:',one===two,);
console.info('one:',one.getName,'two:',two);
跨域方法
- 协议,域名,端口号不相同的资源之间相互通信,就会产生跨域问题。。
- JSONP,CORS,Server Proxy跨域解决方式的应用场景都是用于前后端之间的数据通信,其他跨域解决方案主要是解决窗口页面之间的数据通信。
1. JSONP 只支持 GET 方式的 HTTP 请求。
JSONP的解决方案就是通过script标签进行跨域请求:
- 前端设置好回调函数,并把回调函数当做请求 url 携带的参数。
- 后端接受到请求之后,返回回调函数名和需要的数据。
- 后端响应并返回数据后,返回的数据传入到回调函数中并执行
也可以使用 AJAX GET 请求方式来跨域请求(axios GET 方式跨域同理)
<!-- AJAX GET 请求 -->
<script>
function jsonpCallback(data) {
alert('获取到的数据了,打开控制台瞧瞧');
console.log(data);
}
$.ajax({
type: 'GET', // 必须是 GET 请求
url: 'http://127.0.0.1:3000',
dataType: 'jsonp', // 设置为 jsonp 类型
jsonpCallback: 'jsonpCallback' // 设置回调函数
})
</script>
2. CORS 跨域资源请求需要后端支持(服务器端配置)。
node段设置:
res.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
// 或者使用了 Express 这样的框架
res.header("Access-Control-Allow-Origin", "*");
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据
3. Server Proxy 直接让后端代理发送请求。
服务端代理请求,流程就是 浏览器向服务端A发送请求,服务端A转发请求给服务端B, 服务端B返回数据给A,服务端A再返回数据给浏览器。其中服务端A就是代理服务器。
例子:
<!--服务端代理访问https://cnodejs.org/api/v1/topics接口-->
const url = require('url');
const http = require('http');
const https = require('https');
const server = http.createServer((req, res) => {
const path = url.parse(req.url).path.slice(1);
if(path === 'topics') {
https.get('https://cnodejs.org/api/v1/topics', (resp) => {
let data = "";
resp.on('data', chunk => {
data += chunk;
});
resp.on('end', () => {
res.writeHead(200, {
'Content-Type': 'application/json; charset=utf-8'
});
res.end(data);
});
})
}
}).listen(3000, '127.0.0.1');
console.log('启动服务,监听 127.0.0.1:3000');
4. 其他通过 iframe 跨域与其它页面通信的方式。(扩展)
- location.hash
- window.name
- postMessage
- document.domain
- flash