NUDTcourse开发日志
这不是软件计划书or升级日志,是写给自己的报告:记录知识点、相关工具的配置和使用、debug过程。
目的:记录开发收获,便于回顾总结,力求简练。
NUDTcourse是数据库课要求的一个信息管理系统项目,前后端分离,使用react、LNMP。
导出excel
后端:POI、easyExcel(都是java)
前端:js实现⬇
js文件操作之——导出Excel (js-xlsx) - youryida - 博客园 (cnblogs.com)
基于前端JS导出Excel文件(减轻服务端压力) - 云+社区 - 腾讯云 (tencent.com)
bug: API接口问题
描述:当时误认为php未正确接收表单。
详细:萌新不知道怎么做API测试,打开网络能看到预检(这是第一次听说预检是啥)成功了,后面加一个请求到的文件,但是点开啥都没。
当时的写法(是正确的。记得json要转字符串):
1 | fetch(url, { |
php接收:
1 |
|
自己写了个测试:
1 | ... |
测试发现发送其实成功了,如果直接点网络里请求的php文件是什么都看不到的,误判了。
当时的回应用console.log才能看,原来sql语句错了,取到的变量两边加上单引号。。
结论:自己不熟悉的项目or框架变数太多,可以自己做一个小demo重现bug。当时直接在项目里改,不知道bug出在ajax还是react,范围太大无处下手。
bug: php中文乱码
php从数据库取的数据是
??
:解决:php里加上
mysqli_query($con,"SET NAMES 'utf8mb4'");
php的array转码后变成了unicode码:
{"S1":"\u59d3\u540d":"\u8d75\u4ea6","\u6027\u522b":"\u5973","\u5e74\u9f84":"17","\u7cfb\u522b":"\u5973"}...
解决:给json_encode加上第二个参数
JSON_UNESCAPED_UNICODE
。
php json_encode 中文不转码-php教程-PHP中文网
PHP json_encode函数的参数说明 - 范仁义 - 博客园 (cnblogs.com)
前端路由react-routerV6
后端配置问题
场景:生产环境,切换页面时向后端发送了请求,但因为那个url是做的前端路由,后端找不到页面,返回服务器的404页面。
——为什么在开发环境没有发生404呢?本地启动react项目也是给配了服务器的(像vue用了express),而项目给你把这个服务器配好了。但是生产环境本来是后端路由的,需要手动来配。
- 要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个
index.html
页面,这个页面就是你 app 依赖的页面。 - 给个警告:这么做以后,你的服务器就不再返回 404 错误页面,因为对于所有路径都会返回
index.html
文件,404的URL规则自然是交给前端路由来决定了。你应该在 Vue (React)应用里面覆盖所有的路由情况,然后再给出一个 404 页面。
tomcat配置:直接修改了conf/web.xml,暴力解决(但是控制台还能看见404报错)。
【我以为只会跳到index.html,结果router开始工作,路由到了正确的页面。助かる。。】
参考:
说一说前端路由与后端路由的区别 - 前端南玖 - 博客园 (cnblogs.com)
HTML5 History 模式 | Vue Router (vuejs.org)
解决单页应用 history 模式下部署 tomcat 刷新页面出现 404 - 瞭月 (lervor.com)
js主动使用路由
一般是在页面Link元素配路由,但有时候需要用js实现跳转(比如提交表单后跳转/刷新页面)。
V6文档提供的方法如下,没玩会,目前用的是原生方法。
- 组件必须是函数Hook类型,不能是class类型
- 2这里,useNavigate要在组件里调用,不能套在它的函数里调用
我的遭遇:
使用上面官方的功能,发现没法跳转到当前页面实现刷新。但是为了重新渲染表格,我先跳到首页再跳回来,白白跳转了两次。而且如果使用返回键前进键,会发现网页的乱跳行为,很影响体验orz
不用这个用原生可以吗?试了
reload()
、location.reload()
不行,**window.location.href="XXX"
可以**,那就用这个了。V5已经不能用
this.props.history
了的样子。V6更是改,直接搜博客大多过时了
局部结论:中途把凑合能用的东西强制套上去,浪费了时间。没学完没法避免,但是尽量不要到处套自己会的某方法,有时间要先查查官方想让你怎么做。
参考:
警告:非法 Hook 调用 – React (reactjs.org)
npm
npm常用命令及参数详解 - SegmentFault 思否
使用“npm init”初始化项目 - 你是远方 - 博客园 (cnblogs.com)
Art-template
一开始使用了art-template,换react后就用jsx处理了,主要就是循环生成列表、表格,其他功能不太用的上。
模板引擎 – art-template 现在还有学习模版引擎的必要吗
前端模版引擎 - artTemplate 【上】 - 简书 (jianshu.com) (有两个详细的demo!!)
前端模版引擎 - art-template 【下】 - 简书 (jianshu.com)
template(temid, json)
如果接收不到json或者第二个参数其实是空的,返回的不是渲染好的html而是编译了一个渲染函数(看见函数里边有的字符都被转义了还有很多\n,不懂,懵逼)- 如果返回回来的 JSON 数据是类似数组数据的话,是没有办法直接渲染的。需要对数据做如下包装,才能正常渲染:
1 | template: |
js
如何将json对象转成数组??? - SegmentFault 思否
js字符串的裁剪 - 狗尾草的博客 - 博客园 (cnblogs.com)
JSON使用变量
1 | // 定义空对象 |
异步问题
本来写成两个函数load
、render
结果render
接受不到json。
ajax是典型的异步编程,必须学会回调函数、then(关于promise)。等前面语句运行完有了结果,再执行下面的。
Promise.prototype.then() - JavaScript | MDN (mozilla.org)
1 | function render(tempID, url, id) { |
php
php字符串拼接 - museluo - 博客园 (cnblogs.com)
多行字符串
1 |
|
管理技巧
MVP产品原则
开发一个最小的可行产品,从而快速试错。每次迭代,焦点都在核心流程上
前后端对接
RESTful
⚠还未良好实践
鉴权
⚠还未良好实践
HMAC
hmac主要应用在身份验证中,如下是它的使用过程: 1. 客户端发出登录请求(假设是浏览器的GET请求) 2. 服务器返回一个随机值,并在会话中记录这个随机值 3. 客户端将该随机值作为密钥,用户密码进行hmac运算,然后提交给服务器 4. 服务器读取用户数据库中的用户密码和步骤2中发送的随机值做与客户端一样的hmac运算,然后与用户发送的结果比较,如果结果一致则验证用户合法。
在这个过程中,可能遭到安全攻击的是服务器发送的随机值和用户发送的hmac结果,而对于截获了这两个值的黑客而言这两个值是没有意义的,绝无获取用户密码的可能性,随机值的引入使hmac只在当前会话中有效,大大增强了安全性和实用性。
安全
https
分离方式
- 半分离式,前端负责开发页面,通过接口(AJAX)获取数据跟页面进行数据绑定(类似原来的JSP标签方式),最终是由前端把页面渲染出来,后端只提供数据接口,前端的页面仍需要跟后端服务部署到同一个web容器中,如果web容器挂掉,那么会直接导致页面访问不了
- 全分离式, 前端负责的内容同上,只是前端页面单独部属在一个web容器,前端和后端相互不影响,如果是后端容器挂了,前端可以访问,只是请求不到数据
- 还有一种就是 在前端和后端之间加入node作为服务,node提供一些接口服务,又或者部分页面需要服务端渲染,又或者需要处理一些大并发的问题,如果是需要涉及到一些大数据的查询或者运算,再由node层去跟后端服务(java服务等)进行数据交互,再由node 接口供给前端
用了react后可以全分离也可以都放在nginx下(前端使用的接口是绝对地址,跨域也解决了)
后端是通过nginx挂载php的fastcgi,接收前端发来的请求,对数据库进行相关操作。
前端和后端数据交互的基本知识和常见方式
- 用 form 可以发请求,但是会刷新页面或新开页面;
- 用 a 可以发 get 请求,但是也会刷新页面或新开页面;
- 用 img 可以发 get 请求,但是只能以图片的形式展示;
- 用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示;
- 用 script 可以发 get 请求,但是只能以脚本的形式运行。
- 用 jsonp 实现请求,支持跨域请求。
- 用 ajax 实现页面无刷新的请求。
ajax技术
XMLHttpRequest,结构比较混乱(但出现很久了,使用规模巨大);fetch,新兴的ajax技术(他俩是平起平坐的关系)。axios库是对XHR的封装,而上面两个是原生api。
综合考虑开发难度和兼容性问题,决定选用axios进行前后端的信息交互。 用了fetch原生。
双向通信
WebSocket与消息推送 - 张果 - 博客园 (cnblogs.com)
如何在大型 Web 应用中保持数据的同步更新? - 知乎 (zhihu.com)
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。 优点:后端程序编写比较容易。 缺点:请求中有大半是无用,浪费带宽和服务器资源。
实例:适于小型应用【针对管理员开启轮询怎么样orz】。
长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。 优点:在无消息的情况下不会频繁的请求,耗费资小。 缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。 Comet异步的ashx,
实例:WebQQ、Hi网页版、Facebook IM。
长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。 优点:消息即时到达,不发无用请求;管理起来也相对方便。 缺点:服务器维护一个长连接会增加开销。
实例:Gmail聊天
Websocket:
WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信。
特点:事件驱动、异步、使用ws或者wss协议的客户端socket,能够实现真正意义上的推送功能
缺点:少部分浏览器不支持,浏览器支持的程度与方式有区别。
跨域问题
cors跨域之简单请求与预检请求(发送请求头带令牌token) - SegmentFault 思否
使用 Fetch - Web API 接口参考 | MDN (mozilla.org)
允许跨域
配置nginx:
1 | Access-Control-Allow-Origin: * |
Cookie
最早被提出来的本地存储方式,在每一次 http 请求携带 Cookie,可以判断多个请求是不是同一个用户发起的,特点是:
- 有安全问题,如果被拦截,就可以获得 Session 所有信息,然后将 Cookie 转发就能达到目的。(关于攻击和防范本可以看另一篇文章 吃透浏览器安全(同源限制/XSS/CSRF/中间人攻击))
- 每个域名下的Cookie不能超过20个,大小不能超过4kb
- Cookie在请求新页面的时候都会被发送过去
- Cookie创建成功名称就不能修改
- 跨域名不能共享Cookie
如果要跨域名共享Cookie有两个方法
- 用 Nginx 反向代理
- 在一个站点登录之后,往其他网站写 Cookie。服务端的 Session 存储到一个节点,Cookie 存储 SessionId
Cookie的使用场景
- 最常见的就是 Cookie 和 Session 结合使用,将 SessionId 存储到 Cookie 中,每次请求都会带上这个 SessionId 这样服务端就知道是谁发起的请求
- 可以用来统计页面的点击次数
Cookie都有哪些字段
Name
、Size
顾名思义Value
:保存用户登录状态,应该将该值加密,不能使用明文Path
:可以访问此 Cookie 的路径。比如 juejin.cn/editor ,path是/editor,只有/editor这个路径下的才可以读取 CookiehttpOnly
:表示禁止通过 JS 访问 Cookie,减少 XSS 攻击。Secure
:只能在 https 请求中携带SameSite
:规定浏览器不能在跨域请求中携带 Cookie 减少 CSRF 攻击,详细说明看这里Domain
:域名,跨域或者 Cookie 的白名单,允许一个子域获取或操作父域的 Cookie,实现单点登录的话会非常有用Expires
/Max-size
:指定时间或秒数的过期时间,没设置的话就和 Session 一样关闭浏览器就失效
LNMP配置
原理太长不看:Nginx工作原理和优化总结
💥配置文件详解:Nginx和PHP的配置
- Nginx 是非阻塞IO & IO复用模型,通过操作系统提供的类似 epoll 的功能,可以在一个线程里处理多个客户端的请求。Nginx 的进程就是线程,即每个进程里只有一个线程,但这一个线程可以服务多个客户端。
- fastCGI :为了解决不同的语言解释器(如php、python解释器)与webserver的通信,于是出现了cgi协议。只要你按照cgi协议去编写程序,就能实现语言解释器与webserver的通信。如php-cgi程序。但是webserver每收到一个请求,都会去fork一个cgi进程,请求结束再kill掉这个进程。这样有10000个请求,就需要fork、kill php-cgi进程10000次。 fastcgi是cgi的改良版本。fast-cgi每次处理完请求后,不会kill掉这个进程,而是保留这个进程,使这个进程可以一次处理多个请求。
正向代理是从客户端的角度出发,服务于特定用户(比如说一个局域网内的客户)以访问非特定的服务;反向代理正好与此相反,从服务端的角度出发,服务于非特定用户(通常是所有用户),已访问特定的服务。
URI规范
url 设计规范
管理员可以重新组织服务器上的文件系统结构,而无需改动URI,这就需要URI和真实的服务器文件系统结构之间有一个映射机制,而不是生硬的对应。
隐藏文件后缀名
带后缀名不够美观:nginx一招配置,帮你快速隐藏php后缀名
零散的日记
12.15
封装了fetch,ajax简洁多了。想要使用RESTful 风格,用四种请求方法分别对应了增删改查。但没有用http状态码,url布置、JWT鉴权都还不会做,实在称不上RESTful。
11.25
React 踩坑–input中的value与defaultValue - 墨西哥郊外的晚上* - 博客园 (cnblogs.com)
关于http请求规范:
Using Fetch - Web APIs | MDN (mozilla.org)
reactjs - Javascript: Fetch DELETE and PUT requests - Stack Overflow
大概只有get不该带body,其他带了都有情可原(它们改服务器数据了)
11.23
头次验收。老师建议:用java。php是做小网站的。
我的理解:php太好学了,功能上、性能上不够强。(直接用php是很简洁,所以很多功能不能实现。要想php实现和java一样的功能,也是要学很复杂的框架的)
前端打算换react了,脚手架走起。
——1.27:这时候才换的?
11.6
上完周五的数据库,重看了聂总的视频,结果从周五下午吸收到周六中午🤣
把看的网页堆这里(也有很多放到前端工具 & 概念 (wolai.com)了,要及时回顾)
10.29
师曰:直接显示个php页面上去还不行,要加Model层。
我:Model是啥?
查了巨多MVC、前后端分离、前端工程化(没写过后端,所以什么都拿到前端来搞)。又担心php是不是没有java先进,看了很多知乎上的【xxx是不是过时了】。光是看这些网页花了两三个晚上。确实学到不少,但凭现在的技术落不到实处,决定后端就用php。
收获:及时了解新技术。下面这些就算真过时了,学了对渐进入门有好处,可以帮助理解原理、学习设计方法。(拔草总是比种草有B格hh。但不同于劝退炒股,这是技术文章,看别人的批判是为了更好的了解,注意理性判断)
Spring MVC 过时了吗? - 知乎 (zhihu.com)
为什么我劝你放弃mybatis - 知乎 (zhihu.com)
10.20
开始系统写日志,顺路看到:谈谈开发日志 - 飞鸟_Asuka 。
刚起步时获取的信息比较杂乱,需要整理总结吸收。
10.15
BS5最佳学习网站:Bootstrap5 中文手册-俺老刘
注意时效性,网上很多v3v4的,也不声明自己什么版本。官方文档最靠谱。