久违的更新 - VueJs学习记录

久违的更新 !

在经历了一年的风风雨雨之后,终于结束了考研的艰苦岁月,同时也终于有机会去实现一直存于心中的遗憾,2021年初的开局好像比2020年来的更温和一些(希望是这样!),在考完研的那天,心心念念的姑娘向我发来了讯息,这令我激动万分!于是就这样 我们抓住了2020的尾巴,在2020年年末的时候走到了一起,到目前为止,我们十分甜蜜 希望我们有机会可以把这份甜蜜的序曲变成轰轰烈烈的生活交响曲。

我想和你一起生活,

在某个小镇,

共享无尽的黄昏,

和绵绵不绝的钟声。


正式开始今天的更新

今天是正式进军前端的第一天,也是拜女朋友所赐,才有机会可以系统的学习到这些理论和知识(来自廉价劳动力的叹息 哎~),这次学的是Vue.Js,选他的目的是看中了其前景以及目前的应用场景,从UNI-APP到Hybrid开发,都可以看见Vue的身影


  1. IDE的选择 :这里我选择了使用最为简单的VSCode

  2. Lesson 101 :

    1. 快速建立HTML5标准模板:
      打开VSCode新建一个文件,在编辑栏输入!,按Tab自动补全Html5模板,十分方便!

    2. body页面的处理:
      Vue作为JS引擎,具有强大的处理能力,任何编程语言的第一课都是从hello world开始,可是我今天打算表白我的女朋友,哈哈哈哈

      1
      2
      3
      <body>
      <div id='root'></div>
      </body>

      我们在body页面引入一个id为root的div标签,通过操作vue对其进行插入操作

    3. 创建Vue实例:
      Vue.createApp({}).mount('#root');
      这一步是将实例挂载在id为root的dom元素上

    4. 添加内容:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      Vue.createApp({
      data(){
      return {
      content:1
      }
      },
      mounted(){
      setInterval(() => {
      this.content=this.content+1;
      }, 1000)
      },//页面加载完成后执行
      template:'<div>{{content}}</div>'
      }).mount('#root');

      在将实例挂载到root的标签后,向其内部加入template标签内的内容但是 {content}为JavaScript的替换符,在data内我们定义了返回content:1的变量,因此此时标签被替换为<div>1</div>,但是mounted的意思是指在页面加载完成之后所要执行的内容:setInterval()设定了一个定时器,定时器的执行时间是1000ms一次,定时器要执行的操作是this.content = this.content + 1;,也就是对于data中定义的content进行一个自加的操作,因此页面就完成了一个基本的Counter的功能

  3. 彩蛋 & 总结:

    • 学会了VueJs的基本技巧,同时还写了第一个Vue代码
      ![First Vue](https://api.radiology.link/static/pic/firstvue.png ‘’I Love Niki’’)
    • 今天是她和我在一起心情最差的一天,而且晚上我还火上浇油,想要给她惊喜但是考虑的实在不(粥),拜 钱多多 所赐,要不然我们就打起来了!
    • 最最最后,今天也是她第三次(好多次)![Complain](https://api.radiology.link/static/pic/complain.png ‘’I Love Niki’’)
      鼓起勇气跟她父亲去说我们俩关系的日子,在我编辑这段文字的时候,我的微信正在不断的发来消息提示,希望是好消息哦!虚惊一场,原来是阿姨要换手机

    最后祝大家新年快乐!2021开局顺利!

    周佳璇,我喜欢你 ❤

基于[CURL的优慕课教务系统模拟登陆]

登陆需要用到三个接口:

获取第一次的Cookie:
http://jwc.sdfmu.edu.cn/academic/common/security/login.jsp

利用获取的Cookie获得验证码:
http://jwc.sdfmu.edu.cn/academic/getCaptcha.do

利用验证码和Cookie进行Post登陆:
http://jwc.sdfmu.edu.cn/academic/j_acegi_security_check

将利用到以下知识:

1、Curl不利用CookieJar进行Cookie的存储
2、Curl获取302跳转到的目标页面
3、Curl进行post登陆

第一步:利用Curl获取Cookie,不使用CookieJar

由于是后端对接,所以使用了php进行获取Cookie,不使用CookieJar:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private function getcookie(){
$session = curl_init();
$url = 'http://jwc.sdfmu.edu.cn/academic/common/security/login.jsp';
curl_setopt($session, CURLOPT_URL,$url);
curl_setopt($session, CURLOPT_HEADER, 1); //保留头信息获取cookie
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($session);
curl_close($session);
list($header, $body) = explode("\r\n\r\n", $content);
preg_match("/set\-cookie:([^\r\n]*)/i", $header, $matches);
$temp = $matches[1];
preg_match_all('/JSESSIONID=[A-Za-z0-9=.]+/i', $temp, $cookie);//正则匹配JSESSIONID后的内容
return $cookie[0][0];
}

第二步:利用Cookie得到验证码

由于验证码是图片性质,所以处理起来我用了笨办法,将curl得到的图片进行转存,转存到本地然后返回给前端一个jpg文件名和第一步得到的cookie,因为没有利用session所以只能把cookie给前端,登录的时候再通过ajax返回给我;为了避免图像的重复,利用MD5作为文件名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public function getimg(){
$cookie = $this -> getcookie();
$session = curl_init();
$url = 'http://jwc.sdfmu.edu.cn/academic/getCaptcha.do';
curl_setopt($session, CURLOPT_URL,$url);
curl_setopt($session, CURLOPT_HEADER, 0); //头信息剔除
curl_setopt($session, CURLOPT_COOKIE,$cookie);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($session);
curl_close($session);
$tmpFile = tempnam(sys_get_temp_dir(), 'image');//创建一个缓存文件,用于保存验证码
$resource = fopen($tmpFile, 'w');//打开缓存文件
fwrite($resource,$content);//写入图片
fclose($resource);//关闭
$md5FileName = md5_file($tmpFile);//生成文件MD5,消除歧义
$returnFile = './image/' . $md5FileName . '.jpg';//构造最终返回给前端的文件名
copy($tmpFile, $returnFile);//拷贝到最终文件
@unlink($tmpFile);//删除临时文件
$returnFile = $md5FileName.'.jpg';
$rawData = array('Cookie'=>$cookie,'img'=>$returnFile);//将Cookie以及img信息返回给前端进行加载和二次接力
$response = $this -> encodeJson($rawData);
echo $response;
}


第三步:利用Cookie进行post登陆

通过观察请求包发现:

1
2
3
4
5

发送的post请求是一个raw格式并且有```urlencode()```转码

因此我们先构造一个post包:
>```$post_data = "j_username=".$user."&j_password=".$pass."&j_captcha=".$code;

第二步发现还必须往header中加入content-type:application/x-www-form-urlencoded,否则post raw格式服务端会拒绝,提示验证码错误

因此就得到了前两步的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public function login($user,$pass,$code,$cookie,$img){
$file = './image/'.$img;//得到当时回传的文件名
if (file_exists($file)){
unlink($file);//删除刚才创建的验证码,其实也可以用计划任务删
}
$url = "http://jwc.sdfmu.edu.cn/academic/j_acegi_security_check";//post url
$ch = curl_init();
$post_data = "j_username=".$user."&j_password=".$pass."&j_captcha=".$code;//RAW格式post包
$headers = array(
"content-type:application/x-www-form-urlencoded"
);//构造header
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);//启用post
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);//post data
curl_setopt($ch, CURLOPT_COOKIE, $cookie);//携带cookie post
}

执行到上面的第三步我们发现一个问题,这个是否登录成功会反馈给一个http 302状态码,然而curl好像没办法获得302跳转到的界面,因此就没法判断html内容是否成功了,经过查阅资料发现:curl_getinfo()可以获得HTTP头,也就是可以解析302里面的内容

当我把302解析之后发现返回了一个数组,key下面的’redirect_url’内对应着跳转到的页面如果是http://jwc.sdfmu.edu.cn/academic/index_new.jsp则成功登录,如果是另外一个则登录失败,因此得到了最终版的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public function login($user,$pass,$code,$cookie,$img){
$file = './image/'.$img;
if (file_exists($file)){
unlink($file);
}
$url = "http://jwc.sdfmu.edu.cn/academic/j_acegi_security_check";
$ch = curl_init();
$post_data = "j_username=".$user."&j_password=".$pass."&j_captcha=".$code;
$headers = array(
"content-type:application/x-www-form-urlencoded"
);
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
$content = curl_exec($ch);
$header = curl_getinfo($ch);
if ($header['redirect_url']=="http://jwc.sdfmu.edu.cn/academic/index_new.jsp"){
echo 'true';
curl_close($ch);

} else {
echo 'false';
curl_close($ch);
}

}

前端根据True or False判断是否登录成功,这样就大功告成了!


小结

通过这次的综合训练,学会掌握了Curl的进阶用法,以及正则表达式的用法,虽然用的不熟练但是也是实战了,还学会了利用curl获取302里面的跳转信息判断是否登录正常,这次弄得我快吐了,再也不想写代码了,好好学习了,还是学习简单,心无旁骛了!太费劲了吧!!!

Selenium+Chrome实现一个投票工具

前几天有朋友要参加一个投票,想要刷票一开始我是拒绝的,因为要是在微信的话那就只好去找刷手了,他说投票是在一个app中进行的,我一听:哦?有戏!那我们下下来看一看发现app的逻辑做的很不友好,不用登陆就可以投票,那他是怎么做的限制呢?

第一次尝试:
用chrome抓一下他的post包得到:

POST /*****/******/vote.jsp HTTP/1.1 UserNo=101&UserNo=103&UserNo=104&ServiceId=sjds2020&groupname=1&act=do&openid=&openidMd5=

关注到有openid和openidMd5,首先考虑的是在APP内有一个生成openid的函数,那么在手机端执行一次APP数据清理,打开惊奇的发现又可以投票了,那说明openid和IMEI也不挂钩,那么有没有可能是把openid的相关函数嵌入在webview里呢?分析了一下页面的js很遗憾的是没有,也就是说openidMd5的算法是在APP里面的

那么下面就得开始第二次尝试了:我们要把重心放在如何解开这个APP,这APP在安卓下用了加固保,两个办法闲鱼大法或者下他的IPA,当然我选择第一种:在源码里我发现

OutUrlActivity.this.n = n.a(OutUrlActivity.this.o + "xxxKey123");

那么问题就迎刃而解了:

第二次尝试:
首先构造一个openid,九位数,随机生成九位数
1
2
3
4
5
6
7
8
9
  	def id():
j = 9
id = []
id = ''.join(str(i) for i in random.sample(range(0,9),j)) # sample(seq, n) 从序列seq中选择n个随机且独立的元素;
return id
def gen():
openid = id()
openidMd5 = openid+'xxxKey123'
openidMd5 = hashlib.new('md5', openidMd5.encode("utf-8")).hexdigest()

然后就可以构造post了,但是遇到了一个问题,我默认post的是json一直提示外部投票,当时也没有仔细研究后来发现他的post是raw格式

payload=’UserNo=’+str(user)+’&ServiceId=sjds2020&groupname=’+str(group)+’&act=do&openid=’+openid+’&openidMd5=’+openidMd5

第二次没法发现这个细节于是迫不得已转向了selenium,
不得不说selenium真是一个有利的武器,尤其是结合了jquery那真的太无敌了

1
2
3
4
5
6
7
8
var liarray=$('li');//因为投票的人物都在li标签里,所以获取一下全部的li元素
var num = 0;//找到目标id在标签里的排序
for(var i = 0; i < liarray.length; i++){
if(liarray[i].innerText.indexOf("+str(user)+")>=0){//如果包含则记录num
num = i;
}
}
$(liarray[num]).find('input').click();//找到li元素下面的input点击

将这段结合selenium:
driver.execute_script(js)这样就搞定了一次投票,后来发现效率太低,那得改改策略:
于是发现了raw格式的post,成功进行冲票

不得不说这种投票确实很无聊天天靠刷票,要不是利益相关谁能保证给你投票呢?

开发日志 [Final]

这是一篇开发小结

 这可能是考研之前开发的最后一个功能了,随着今天(2020-03-15)全部功能的上线,以后的迭代更新和开发如果不是重大bug,估计版本号一直停留在 V0.3.3 V0.4.0了

  等到疫情过去开学,就把版本号变成V1.4.0,三次大迭代,数次小更新我也记不清自己到底更新啥了 2333

其实时间功能也不麻烦 只不过自己怕麻烦 去掉了Unique加了几行就搞定了

1
2
3
4
5
6
7
8
9
10
$presql = "SELECT * FROM `user` WHERE `seat`=? AND `datepicker`=?";
$prestmt = $conn->prepare($presql);
$prestmt -> bind_param("ss",$seat,$dateselect);
if($prestmt -> execute()){
$rawData = array('msg'=>'Booked');
$response = $this->encodeJson($rawData);
echo $response;
else {
Subscribe();
}
V0.1.0版本有了最初始的预约功能但是位置和书库都选不了

V0.2.0版本有了书库位置还有日期选择,最重要的是加入了预约短信!

V0.3.0版本有了快速抢座功能

V0.4.0版本增加了最终的日期选择

V1.0.0 Final正式版 -- 停止更新


 拼尽全力,考研逆袭  - HaroldX

就写这么多吧,也算是给自己这么多年的编程生涯画上句号了,终于做了次对同学们有帮助的事情,祝福大家成功上岸

Keep Fighting Keep Loving

勇往无前的阿盘 敬上

2020-03-15

开发日志-图书馆预约

开发日志 - Lab4Reserve

这是一篇开发日志 - 可能不涉及技术层面 因为我也不会太多技术 2333

此条更新于 2020-01-24


已经实现的功能:

  • 短信通知
  • 预约防重复
  • 预约(核心功能)选座-选区域
  • 高峰时期抢位置

即将实现的功能:(取决于难度和我学习时间安排):

  • 微信通知(估计实现不了了 wxpy不能用了)
  • 日期预约 (估计也实现不了了,太难了)
  • 高峰时期(开馆期间的随机抢位)

如果大家有什么好的建议欢迎联系我 - Wechat : Harold_Xin


 说实话,从开始立项开发座位预约到结束其实就用了3天零碎时间 加起来的代码能有200行?但是后来上线时间还是拖到了一个星期之后,这是因为基础不牢,地动山摇,我从来不会PHP只好一边百度一边写 吃百家饭,不过对于一个不从事职业Programmer的医学生,地动山摇就地动山摇吧,反正专业课扎实一点,能看病能考研就够了,别的都是爱好【要命思想】

在这期间遇到了很多坑:

  • 比如说我的stem->prepare一直返回一个false,我真的无奈,检查了俩小时后来发现:我变量名重复了

    $conn = new mysqli($this->server, $this->dbuser, $this->dbpass, $this->dbuser[应该为dbname]);

    虽然我的dbuser和dbuser都一样,还是莫名其妙的False,你说这事儿搞的,大意失荆州啊!
  • 还有很多乱七八糟的bug比如js和Python字符串相加直接整个+号就👌,php得整个[string].[string],这我哪知道啊?又莫名其妙整了半个小时,佛了
  • bug反正永远都有很多,后端的bug解决起来都好办,怕的是前端,前端那不叫bug叫审美,我这大老爷们女票都说:你有审美吗?所以我整个前端真的是费了洋劲了,一把辛酸泪,不过好歹这个模板不错,可以推荐给大家,有需要的联系我,虽然花了大洋买但是买了就要共享对不对?
    (得了,图片不会上传,改天回了再说吧)
    ![UI](https://www.radiology.link/images/ui.png "UI")

还好最后还是成功上线了,目前为止访问量还算大?访问量不谈,重要的是能对同学有帮助就够了(其实还是为了自己哈哈哈哈)

先写这么多 一点了都 明天还有候老师的早课 估计又得点名批评我,大家再见!👋

嗨 很高兴认识你~

嗨~很高兴认识你

如果你是从RadioLogy-Lab来的,那看来我们是校友哦,自我介绍一下:


自我介绍:

我是一只医学生,(废话,都说是同一个学校的了);没学医之前励志做一个Programmer,给自己起的英文名叫HaroldXin,现在被同学叫做阿盘,因为以前的体型原因(现在已经瘦下来了嗷!)虽然学医是被逼无奈,但是后来还是慢慢喜欢上了学医,以前稍微有一点计算机方面的本领,可以更好地辅助我或者辅助大家学习,举个🌰:比如说上面的预约系统,我的本意域名用Lab开头其实是想做更多的实验内容,例如在线阅片啊巴拉巴拉巴的,可是那些太深奥了,我都不会,能做成的好像也就只有一个预约系统了,当然其他稍微简单点的比如说什么毕设之类的可能也能做,哈哈哈哈,之前也有过APP开发经验只不过不是原生开发罢了,毕竟不是专业人士嘛~


如果我有什么能帮上您的或者您对RadioLogy-Lab的开发或功能有任何建议或意见,切记!请不要第一时间找学校告我的黑状,可以先和我沟通 有什么事我们好商量嘛~要不然学校知道了大家都没得玩咯。

您可以通过下面的方式联系到我:

邮箱:<haroldxin@foxmail.com>

WeChat : Harold_Xin

同时祝福您在学习路上一帆风顺,学业有成!
HaroldXin 敬上

Hello World

欢迎来到阿盘的 Hexo! 之前有很多次想要做一个小的blog来记录自己的成长,学习经历还有和小可爱的生活故事,可惜都是虎头蛇尾,万事开头难,希望这一次的我能坚持下去,对啦~你也可以在另一个地方访问到我家小可爱的blog


此条置顶更新于: 2020-01-24


1
$ 很高兴认识你们~请多多指教~

请我喝杯咖啡吧~

支付宝
微信