Coder Social home page Coder Social logo

blogsource's People

Contributors

fangmd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

blogsource's Issues

Web安全:XSS攻击

XSS 是什么

XSS: Cross-Site Scripting, 跨站脚本攻击

原理:恶意攻击者向 web 页面中插入恶意可执行网页脚本代码,用户游览时代码被执行达到攻击的目的。

简单点说就是, 有用户输入的内容直接显示到html上的时候,可能会触发 XSS 攻击。

比如: 用户将下面的内容输入到输入框,页面直接显示用户输入内容的时候,这段脚本就会被执行。

<script>alert('haha')</script>

攻击类型

  1. 非持久型(反射型)

特点:

  • 脚本不过服务器存储,直接通过一次http请求拿到用户数据

防范措施:

  • 保证页面所有渲染数据来自服务器
  • 前端渲染前做 escape 转义编码 escape(string)
  1. 持久型 XSS (存储型)

将一段脚本通过表单或http请求提交到数据库里面,网页从数据读取到数据后渲染执行了恶意代码。

攻击成功需要满足的条件:

  • POST 请求对于数据没有做转义直接存入数据库
  • 后端从数据库中取出数据时没有转义
  • 前端拿到数据后没有转义直接渲染

XSS 预防

  1. CSP 内容安全策略

开启 CSP 的两种方式:设置 HTTP Header 中的 Content-Security-Policy设置 meta 标签的方式

只允许加载本站资源: Content-Security-Policy: default-src 'self'
只允许加载 HTTPS 协议图片: Content-Security-Policy: img-src https://*
允许加载任何来源框架: Content-Security-Policy: child-src 'none'

在 HTML 中设置内容安全策略

<meta http-equiv="Content-Security-Policy" content="form-action 'self';">

在服务端添加 HTTP 头:

http.createServer((req, res) => {
        const html = fs.readFileSync('index.html', 'utf8');
        res.writeHead(200, {
            'Content-Type': 'text-html',
            'Content-Security-Policy': 'default-src http: https:' 
        });
        res.end(html);
}).listen(9000);

使用 Nginx 给HTTP添加请求头

  1. HttpOnly Cookie

预防XSS攻击窃取用户cookie最有效的防御手段。

Web应用程序在设置cookie时,将其属性设为HttpOnly,就可以避免该网页的cookie被客户端恶意JavaScript窃取,保护用户cookie信息。

使用 Nginx 添加请求头

服务端代码添加请求头

  1. 转义字符
function escape(str) {
  str = str.replace(/&/g, '&amp;')
  str = str.replace(/</g, '&lt;')
  str = str.replace(/>/g, '&gt;')
  str = str.replace(/"/g, '&quto;')
  str = str.replace(/'/g, '&#39;')
  str = str.replace(/`/g, '&#96;')
  str = str.replace(/\//g, '&#x2F;')
  return str
}

Nginx

作用:

  1. 静态文件服务器
  2. 反向代理(缓存加速,负载均衡)

优点:

  1. 负载均衡:方便横向扩充
  2. 反向代理:隐藏真实服务器
  3. 动静分离

Taro 记录

遇到的问题:

  1. 微信开发者工具问题:卡死,UI异常,log慢
  2. 微信小程序富文本支持不好

如何做 Web SEO

搜索引擎如何工作

搜索引擎通过一个 网络爬虫 去探索网站并且添加索引。

过程包含3个步骤:

  1. 爬取内容:首先有一个 网页url列表,爬虫依次爬取这些网页中的内容,发现新的 url 就会添加到 网页url列表 中。
  2. 添加索引: 爬虫爬取网页内容后,分析内容中的数据(文字,图片,视频), 存储分析后的结果到数据库中。
  3. 搜索结果显示:用户发起搜索后,搜索引擎根据各种规则显示搜索结果。规则因素包括:地理位置,语言 ,设备,搜索习惯...

seo 一些操作

保持内容更新

新:

  1. 新内容
  2. 跟热点,网页内容加入一些时下热门搜索的内容

内容展现形式优化

相对于图片和视频,文本内容更容易被搜索引擎处理

外链引流

在其他一些热门的网站上,传播自己的站点。让网页容易被搜索爬虫捕获到。

如何确定网站能被搜索到

搜索的时候指定网址,比如: site:wikipedia.org., 如果没有内容,就表示没有被搜索引擎爬过。

google seo

  1. 上传 sitemap 到 Search Console

参考文档

跨域方案

JSONP

最早出现的跨域方案

缺点:

  1. 由于 jsonp 是使用 script, img, iframe 没有同源限制的标签,所以它只支持 get 请求。
  2. 错误处理机制不完善

优点:

  1. jsonp 可以兼容低版本游览器

例子:

// test.html
<script>
  function test(data) {
    console.log(data);
    return data;
  }
</script>
<script
  type="text/javascript"
  src="http://127.0.0.1:8090/v1/system/user/getTotal?callback=test"
></script>

请求结果通过 get 请求参数 callback 设置

Vue 中第三方库: jsonp

CORS 跨域资源共享

原理: 使用 XMLHttpRequest 发送请求,增加一些字段告诉服务器允许跨域,需要服务端支持。

优点:

  1. 支持多种请求
  2. 处理机制完善
  3. 符合 http 规范,对于复杂请求,多一次验证,安全性更好

缺点:

  1. 不支持 IE10 一下游览器
客户端:

// 创建一个实例
const server = axios.create({
    // 将我们访问的地址设为baseURL
    baseURL: "http://127.0.0.1:8090",
    // 设置超时时间
    timeout: 5000,
    headers:{
        "Content-Type":"text/plain",
        "Access-Control-Allow-Credentials": true
    }
});


"Access-Control-Allow-Origin":"*"

proxy 服务器代理

代理转发,nginx, webpack devserve

Flutter App 如何做异常捕获

try catch 捕获异常

利用语言中异常捕获的功能,捕获一些可预见的异常。

需要注意的是,try catch 不能处理异步异常, 比如:

try{
    Future.delayed(Duration(seconds: 1)).then((e) => Future.error("xxx"));
}catch (e){
    print(e)
}

Flutter 内置的异常捕获机制

Flutter 对于 UI 层的异常捕获

framework.dart

abstract class ComponentElement extends Element {
   //...
  @override
  void performRebuild(){
    Widget build;
    try{
      build = build();
    } catch (e, stack){
      build = ErrorWidget.builder(_debugReportException(...))
    }
  }
}

这里 ErrorWidget 是异常内容展示的 Widget, 异常具体信息在 FlutterErrorDetails 对象中,_debugReportException 构建了 FlutterErrorDetails 对象。

_debugReportException() // 这个函数做了两件事情: 1. 构建 FlutterErrorDetails 对象并返回。2. 将 FlutterErrorDetails 通知给  FlutterError 

FlutterError.reportError(details);

FluterError 接收到错误信息后最终执行内部的静态函数 onError:

static FlutterExceptionHandler? onError = (FlutterErrorDetails details) => presentError(details);

这里 presentError -> dumpErrorToConsole 默认的异常处理方式是接收到异常并打印到控制台。

在 Release 版本下,我们不需要将异常打印到控制台,所以这里我们可以重设置 FlutterError.onError 收集异常。

这也是 firebase_crashlytics 中的异常捕获方式:

FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;

其他异常

空指针异常,一些异步异常,FlutterError.onError 没有捕获到。

可以使用 Dart 中的 runZoned 捕获异常

Zone 相当于一个代码沙箱,可以捕获所有未被处理的异常。

参考 firebase_crashlytics 中对于 Zone 的使用:

runZonedGuarded<Future<void>>(() async {
    // ...
  }, FirebaseCrashlytics.instance.recordError);

客户端项目总结

一个客户端项目开发需要考虑的点。

基本

  1. 项目基础架构选择:MVC, MVP, MVVM
  2. UI 适配:目前移动端方案是更具屏幕宽度等比缩放
  3. UI 网络图片加载:图片是内存大户,在使用的时候要做3级缓存(内存>本地>网络),图片加载过程中设置占位图,加载失败状态图
  4. UI 异形屏处理: 安全区设置
  5. 数据2层结构:Repository -> DBService | NetService -> Entity
  6. DBService: 数据库方案(Sqlite, NoSQL数据库)
  7. NetService: 网络请求方案, 请求拦截器,统一错误处理, 请求取消功能,统一 Loading 设置
  8. 数据持久化方案:网络请求过程中数据持久化,格式:JSON | msgpack
  9. 状态管理方案:目前前端技术栈中都是用状态管理方案来实现跨组件更新数据,Android/iOS 使用 EventBus 类方案
  10. 高频/实时数据刷新方案:websocket , Http 心跳
  11. 线上错误上报机制:通常使用第三方服务收集错误。错误收集的原理是给App添加全局的错误捕获功能,不同语言有不同的具体错误捕获方法。
  12. 数据埋点方案

优化

  1. 包体积优化:图片压缩,图片倍图的选择,代码混淆
  2. UI 优化:保证 60HZ 刷新

主要思路:保证 UI 线程没有大量的操作,如果需要有大任务要执行的可以在子线程中处理。

安全

  1. 代码混淆
  2. 加固:Android apk 加固
  3. 网络请求采用 Https, 传输中的数据做加密

工程角度

  1. 代码分层
  2. 代码规范:使用代码格式化工具,代码检查工具
  3. UI 组件封装,形成基础库独立维护
  4. 项目模块化管理

npm 常用命令记录

检查依赖是否需要升级

npm outdated

查看 npm 全局安装了那些包

npm ls -g --depth 0

npm 全局包安装位置 /usr/local/lib/node_modules

操作全局安装包

npm i -g [xxx]
npm uninstall -g [xxx]

缓存清除

缓存位置: ~/.npm

 npm cache clean --force

升级 npm 版本

npm update -g npm

NodeJS

  1. NodeJS 在服务器上实现单线程和异步I/O

Dart

语言特性:

  1. OOP: 面向对象(Java), extend, implement, mix
  2. function 可以作为对象直接使用(JS, Go)
  3. 强类型:在代码书写阶段就能发现语法错误(JS)
  4. 支持弱类型:在很大程度上提高的代码灵活性(JS)
  5. 不支持反射:导致没有优雅的JSON解析框(Java Gson)
  6. 同时支持JIT/AOT: 保证编码阶段代码实时运行,也能保证打包后代码的运行效率和减少包体积

兼具 Java 的严谨和 JS 的灵活

前端项目总结

基本

  1. 技术选型:Vue, React
  2. 移动端适配方案:vwvh px2vw 插件
  3. css 预编译:less, sass
  4. 图片加载优化方案:OSS, CDN, 图片压缩
  5. 状态管理方案:Vuex
  6. 网络层: axios, axios 自定义配置 请求拦截器,请求结果拦截器(统一的错误处理,token 刷新,埋点)
  7. 打包方案:webpack 常用插件(less, https, 图片处理插, 代码压缩插件, 去除 console)

优化

安全

  1. XSS 跨站点脚本注入:2种 过数据库和不过数据库
  2. CSRF: Cross Site Request Forgery, 跨站请求伪造
  3. iframe 点击劫持

工程角度

  1. 代码规范相关:ESLint 做代码检查,Prexxxx 代码格式化, githook 做强制格式化

序列化与反序列化

概念

  1. 序列化:将对象状态信息转换为可以存储或传输的形式的过程。

  2. 反序列化:将数据包转换成对象状态信息。

常见的传输通道: 网络传输,跨进程通讯,跨语言环境通讯。

数据包:二进制(byte[])

序列化,反序列化方法

  1. xml
  2. json
  3. thrift: facebook 出品
  4. Protobuf
  5. Avro
  6. msgPack

技术团队效率/内部平台

  1. 埋点系统
  2. 大前端(前端/RN/App)上线系统
  3. Api 管理系统
  4. 需求/bug/wiki 管理系统
  5. 后台管理系统
  6. git 版本管理系统
  7. npm 私有源
  8. 性能监控平台
  9. 数据监控平台
  10. 组件管理平台

JavaScript 内存

https://cnodejs.org/topic/5ffea02ea2a2137beaf6e206

内存硬件

  1. CPU 内高速缓存(几M)
  2. RAM 内存

栈与堆(Stack & Heap)

栈内存小1M,适合存放生命周期短,占用空间小的数据。

堆内存大,适合存放生命周期长,占用空间大的数据。

  1. 函数调用的时候创建栈帧
  2. 函数内部原始类型数据直接存储在栈中,引用类型(引用存在栈,引用的值存在堆(变量->栈内存中的引用->堆内存中的值))
  3. 全局变量和闭包引用的变量存储在堆内存
  4. 原始值是不可变的,存储在栈中,新的原始值会开辟新空间。

内存生命周期

分配 -> 使用 -> 释放

  1. 可达性:从全局变量开始查找,能否找到某个变量
  2. 内存泄漏:不能被 GC 回收的内存

垃圾回收算法:

  1. 标记-清除:根据是否处于上下文内标记
  2. 标记-整理:处理内存碎片化
  3. 引用计数:已经弃用

根据内存管理机制,堆内存分为:

  1. 新世代:新的变量值
  2. 旧世代:旧的变量值

内存管理

  1. 全局变量

对于不用的全局变量,要赋值为 null, 让 GC 可以回收变量

  1. 隐藏类

V8内部给对象分配了一个隐藏类,用于提升对象性能

  1. 闭包

注意释放闭包内存,赋值null

游览器内核&JavaScript引擎&游览器渲染原理

游览器内核

常见的游览器内核:

  • Gecko:早期被Netscape和Mozilla Firefox浏览器浏览器使用;
  • Trident:微软开发,被IE4~IE11浏览器使用,但是Edge浏览器已经转向Blink;
  • Webkit:苹果基于KHTML开发、开源的,用于Safari,Google Chrome之前也在使用;
  • Blink:是Webkit的一个分支,Google开发,目前应用于Google Chrome、Edge、Opera等;

游览器处理 html 过程

排版引擎(layout engine)、页面渲染引擎(rendering engine)

a

处理 html, css 生成 DOM,渲染DOM

JavaScript 引擎

作用:执行 JavaScript 代码。将 JavaScript 代码转换成 CPU 指令集后执行。

常见的 JavaScript引擎:

  • SpiderMonkey:第一款JavaScript引擎,由Brendan Eich开发(也就是JavaScript作者);
  • Chakra:微软开发,用于IE浏览器;
  • JavaScriptCore:WebKit中的JavaScript引擎,Apple公司开发;
  • V8:Google开发的JavaScript引擎,Chrome 浏览器;

V8

V8 引擎由 C++ 编写。

V8 引擎中由 3 大部分:

  1. Parse 模块:将 JavaScript �代码转换成 AST(抽象语法树)
  2. Ignition 解释器:将 AST转换成 ByteCode(字节码)
  3. TurboFan 编译器:将字节码编译成机器码

Node.js

内部使用 V8来执行JavaScript代码的,服务器端JavaScript运行环境。

小程序生态状况

2020/12/9

框架 开发框架 Github Stars 支持平台 Github Used By 团队
Taro React/Vue/Nerv 22.7K 微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5 6K 京东,58
uni-app Vue 27.7k 小程序(微信/支付宝/百度/字节跳动/QQ/钉钉)、App(iOS/Android)、H5 1.8K xx
kbone Vue/React - H5/微信 - 官方

CI/CD

基本概念

  1. CI 持续集成(Continuous Integration)

解决当项目多个分支同时开发时,代码合并问题。

CI: 实现代码自动合并,并且执行自动化测试和单元测试。

  1. CD 持续交付(Continuous Delivery)/ 持续部署(Continuous Deployment)

CD: 将代码自动部署到测试或生产环境

参考:https://www.redhat.com/zh/topics/devops/what-is-ci-cd

对称加密与非对称加密

基本介绍

  1. 对称加密

加解密都用同一串密钥。对称加密只有一个私钥。

优点:效率高,速度快。

常见算法:DES, AES

  1. 非对称加密

加解密使用不同的密钥,密钥分为:公钥,私钥。公钥加密私钥可以解密,私钥加密公钥可以解密。

优点:更加安全,速度慢,加密长度有限制,应用场景更广泛(玩法更多)。

常见算法:RSA

应用场景

对称加密 AES

更具密钥长度细分为:AES-128, AES-192, ARS-256

5种加密模式:CBC、ECB、CTR、OCF、CFB
填充方式: NoPadding,PKCS5Padding,ISO10126Padding

使用 AES 加密需要的元素:密钥,IV, 加密模式,填充方式(padding)

import 'package:encrypt/encrypt.dart';

void main() {
  final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit';
  final key = Key.fromUtf8('my 32 length key................');
  final iv = IV.fromLength(16);

  final encrypter = Encrypter(AES(key));

  final encrypted = encrypter.encrypt(plainText, iv: iv);
  final decrypted = encrypter.decrypt(encrypted, iv: iv);

  print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit
  print(encrypted.base64); // R4PxiU3h8YoIRqVowBXm36ZcCeNeZ4s1OvVBTfFlZRdmohQqOpPQqD1YecJeZMAop/hZ4OxqgC1WtwvX/hP9mw==
}

非对称加密 RSA

加解密:

import 'dart:io';
import 'package:encrypt/encrypt.dart';
import 'package:pointycastle/asymmetric/api.dart';

void main() {
  final publicKey = await parseKeyFromFile<RSAPublicKey>('test/public.pem');
  final privKey = await parseKeyFromFile<RSAPrivateKey>('test/private.pem');

  final plainText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit';
  final encrypter = Encrypter(RSA(publicKey: publicKey, privateKey: privKey));

  final encrypted = encrypter.encrypt(plainText);
  final decrypted = encrypter.decrypt(encrypted);

  print(decrypted); // Lorem ipsum dolor sit amet, consectetur adipiscing elit
  print(encrypted.base64); // kO9EbgbrSwiq0EYz0aBdljHSC/rci2854Qa+nugbhKjidlezNplsEqOxR+pr1RtICZGAtv0YGevJBaRaHS17eHuj7GXo1CM3PR6pjGxrorcwR5Q7/bVEePESsimMbhHWF+AkDIX4v0CwKx9lgaTBgC8/yJKiLmQkyDCj64J3JSE=
}

加密有数据包长度限制

验证签名:

 final publicKey = await parseKeyFromFile<RSAPublicKey>('test/public.pem');
 final privateKey = await parseKeyFromFile<RSAPrivateKey>('test/private.pem');
 final signer = Signer(RSASigner(RSASignDigest.SHA256, publicKey: publicKey, privateKey: privateKey));

 print(signer.sign('hello world').base64);
 print(signer.verify64('hello world', 'jfMhNM2v6hauQr6w3ji0xNOxGInHbeIH3DHlpf2W3vmSMyAuwGHG0KLcunggG4XtZrZPAib7oHaKEAdkHaSIGXAtEqaAvocq138oJ7BEznA4KVYuMcW9c8bRy5E4tUpikTpoO+okHdHr5YLc9y908CAQBVsfhbt0W9NClvDWegs='));

AES+RSA 对接口参数进行加密

流程:

  1. 服务器端生成 RSA公私钥,将公钥给客户端
  2. 客户端自己创建一个 AES密钥
  3. 客户端发起请求,使用 RSA公钥 加密 AES密钥,使用 AES密钥加密其他参数(data)
// 请求参数
pk: xxxxxxx,
data: xxxxxxxx
  1. 服务器端收到请求后,使用 RSA私钥解密 pk 参数,得到 AES密钥。使用 AES密钥解密 data 数据。

提成加解密性能,同时解决RSA加密长度限制问题。

前端开源库&工具库记录

加粗/斜体的是正在使用的

css

  1. normalize.css:初始化 css

  2. balloon.css:鼠标悬浮提示

  3. Tailwind: css 框架

  4. bulma: css 框架

  5. unocss

JavaScript

  1. day.js:日期库
  2. momentjs
    老牌时间库,体积大

交互

  1. interactjs 手势移动/手势缩放
  2. hammer.js 手势操作
  3. https://daybrush.com/moveable/
    适合做编辑器
  4. Sortable 拖动排序
  5. driver.js 页面引导库

Canvas 工具

Other

  1. 在线编辑器 monaco

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.