成绩查询小项目笔记
0、前言
前几天大哥通过抓包“西科大官方APP”get到了它的查询成绩的接口,甩给我玩。既然有接口了就好好利用一下,给它做成一个简易的小程序。
用什么做呢?MFC不熟悉,Qt需要的动态链接库太多,Java不会,最初想到的两种解决方案就是微信小程序和JavaScript(虽然JS也不会)。
说做就做,结果微信小程序要配置服务器才能去访问接口,我的域名还没有下来,因此微信小程序GG,那就用JavaScript吧,还可以放到我的博客上方便大家使用。
自称成绩查询器
1、大概思路
有了接口这个大概思路就很清晰了:
这是最初最完美的设想,但是因为各种各样原因最终还是没能实现这个设想,具体原因后面会分析到。
2、功能实现
前端
对于我这种没有审美观的人来说,前端简陋一些就行,能实现功能就可以了,直接贴代码了:
<header>
<meta charset="utf-8">
</header>
<body>
<div style="width: 100%;height: 100%;">
<div align="center" >
姓名:<input type="text" id="name" placeholder="你的名字"><br/>
学号:<input type="text" id="id" placeholder="西南科技大学学号"><br/>
年份:<input type="text" id="year" placeholder="∞~2017"><br/>
学期:<input type="text" id="term" placeholder="1或2(1为下半年2为上半年)"><br/>
<br/>
<button style="width:200px;" onclick="se();">确定</button>
</div>
<div id="tb">
</div>
<div align="center">
<br/>
<span style="font-size:50px;color:red">将网页内容复制到下面的编辑框中</span>
</div>
<textarea style="width: 80%;height: 500px; margin-left: 10%; margin-right: 10%; margin-top:25px; " oninput="change();" id="texts"></textarea>
</div>
</body>
前端界面也就不讲什么了,大概说一下每一个部分是做什么的吧:
填写基本信息的表单
姓名:<input type="text" id="name" placeholder="你的名字"><br/>
学号:<input type="text" id="id" placeholder="西南科技大学学号"><br/>
年份:<input type="text" id="year" placeholder="∞~2017"><br/>
学期:<input type="text" id="term" placeholder="1或2(1为下半年2为上半年)"><br/>
将表单提交给后台并实现界面跳转的button
<button style="width:200px;" onclick="se();">确定</button>
用于渲染得到的成绩的表格
</div>
<div id="tb">
</div>
提示文字
<div align="center">
<br/>
<span style="font-size:50px;color:red">将网页内容复制到下面的编辑框中</span>
</div>
用于填写接口返回信息的编辑框
<textarea style="width: 80%;height: 500px; margin-left: 10%; margin-right: 10%; margin-top:25px; " oninput="change();" id="texts"></textarea>
后台
这部分是重中之重,前端糟糕的我还是要把后台写的好一点的(所以后台踩坑最多)
<script language="javascript">
se = function () {
var name;
var id;
var year;
var term;
var ur;
name = document.getElementById("name").value;
id = document.getElementById("id").value;
year = document.getElementById("year").value;
term = document.getElementById("term").value;
ur = "https://lightapp.weishao.com.cn/api/score/scoredata/find?xn=" + year + "&xq=" + term + "&schcode=swust&stucode=" + id + "&time=1532073315868";
if (ur.length > 120)
window.location.href = ur;
else {
alert("请输入正确信息!");
};
}
change = function () {
var str = document.getElementById("texts").value;
var test = eval('(' + str + ')');
console.log(test);
var table = document.createElement("table");
table.border = '1';
table.width = '100%';
var tr, td;
for (var i = 0; i < test.data.items.length; i++) {
tr = table.insertRow(table.rows.length);
for (var j = 0; j < 5; j++) {
td = tr.insertCell(tr.cells.length);
switch (j) {
case 0:
td.innerHTML = test.data.items[i].kcmc;
break;
case 1:
td.innerHTML = test.data.items[i].cj;
break;
case 2:
td.innerHTML = test.data.items[i].xf;
break;
case 3:
td.innerHTML = test.data.items[i].jd;
break;
case 4:
td.innerHTML = test.data.items[i].xkkh;
break;
}
td.align = "center";
}
}
document.querySelector("#tb").appendChild(table);
}
</script>
下面着重介绍一下后台的辛酸历程:
声明定义变量和函数
对于JavaScript小白的我来说,所有东西都要从零开始,甚至包括定义变量和函数……
声明定义变量
在JavaScript中,变量都是弱类型的,弱类型的意思就是不用我们定义它是什么什么类型,它可以根据需要自动转换。
我们定义一个变量比如x,可以直接写
var x;
很简单不是吗?当然现在这个x还没有值,因此当前的x也就没有类型。我们可以给这个变量赋值:
x=1; //现在x是一个整形变量
x=1.1; //现在x是一个浮点型变量
x='c'; //现在x是一个字符变量
x='china'; //现在x是一个字符串
声明定义函数
因为JS是弱类型的,所以JS里声明定义函数也没有返回值类型,直接按照标准格式声明定义函数就行了:
/*格式1*/
DoSomething=function(参数列表){
//函数体
}
/*格式2*/
function DoSomeThing(参数列表){
//函数体
}
其中这个参数列表可以直接写a,b,c啥的,不用写类型。
作用域
作用域其实在各种编程语言中都大同小异。在块内部的属于局部变量,最外面的是全局变量。
获取表单信息
var ValueName=document.getElementById("引号里写html标签的id").value;
通过这个函数就可以获取到表单中填写的字符串并且将字符串保存到前面的变量ValueName中,方便一会使用。
跳转到一个新的页面
window.location.href="引号里面的是新的界面的地址"
我们可以通过这个函数来跳转到一个新的页面,把这个函数绑定到button的onclick事件上可以实现一个类似于HTML里面a标签的功能。
警告提示窗口
alert("引号里是提示信息");
通过这个函数,我们可以用来提示用户的错误操作或者危险警告啥的。
修改指定HTML标签属性
var ValueName=document.getElementById("HTML标签id");
ValueName.标签属性=Value;
这段代码是不是有些熟悉呢?没错,上面获取表单信息的时候就有用到。其实获取表单信息就是获取表单标签的value属性。
通过这个函数,我们可以任意在后台修改HTML标签的属性值。
向指定HTML标签添加文字内容
var ValueName=document.getElementById("HTML标签id");
ValueName.innerHTML="要添加的文字内容";
好吧,这个代码和上面的很像,其实可以理解为标签的innerHTML属性就是标签后面紧跟的文字。
JSON
先放上菜鸟教程JSON 教程 | 菜鸟教程
这里主要说一下字符串转为JSON对象以及读取JSON对象信息。
字符串转为JSON对象
var ValueName = eval('(' + str + ')');
通过这个操作,可以将str字符串里面的信息转为JSON对象储存在ValueName里,前提是str字符串的格式要符合JSON对象格式。
读取JSON对象指定信息
这里我先给一段JSON对象(摘自菜鸟教程)
{"sites": [
{ "name":"菜鸟教程" , "url":"www.runoob.com" },
{ "name":"google" , "url":"www.google.com" },
{ "name":"微博" , "url":"www.weibo.com" }
]}
如果我想读取这个“google”,我应该怎么写呢?答案在下:
var ValueName=sites[1].name;
其实JSON对象就是一个对象,读取对象里面的信息在C++、Java里面还少吗?
document.querySelector(“#tb”).appendChild(table);
document.querySelector("#tb").appendChild(table);
这段代码是最后一个没有讲明的代码了,我们来看看它都有什么作用:
querySelector("HTML标签");
菜鸟教程解释:querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素。HTML DOM querySelector() 方法
appendChild(结点对象);
菜鸟教程解释:appendChild() 方法可向节点的子节点列表的末尾添加新的子节点。HTML DOM appendChild() 方法
3、纪念我踩过的坑
写这一章是很有必要的,不论上面实现过程多么艰辛,都只是一个结果,最浪费时间并且最有用的东西,还是这些坑。
当然,还记得最开始的流程图嘛?那个流程图上的功能我还是没有完全实现,就是因为这里的这些坑。
访问接口
有了接口那么就可以访问一下接口了,访问接口然后把接口返回的信息存到后台并处理。那么怎么访问接口呢?
原生js的ajax请求 - Cynthia-milk - 博客园
//步骤一:创建异步对象
var ajax = new XMLHttpRequest();
//步骤二:设置请求的url参数,参数一是请求的类型,参数二是请求的url,可以带参数,动态的传递参数starName到服务端
ajax.open('get','getStar.php?starName='+name);
//步骤三:发送请求
ajax.send();
//步骤四:注册事件 onreadystatechange 状态改变就会调用
ajax.onreadystatechange = function () {
if (ajax.readyState==4 &&ajax.status==200) {
//步骤五 如果能够进到这个判断 说明 数据 完美的回来了,并且请求的页面是存在的
console.log(ajax.responseText);//输入相应的内容
}
}
这是直接从别人的博客上摘抄下来的代码,其实这个就能实现访问接口并且获取数据了。
但是我们真正的运用上呢,好吧,这里就出现了一个问题,一个名为跨域的问题。
跨域问题以及解决方案大家可以看这篇博客:前端常见跨域解决方案(全) - inroam - 博客园
那么最后跨域问题解决没有呢?嗯,跨域问题解决了,我使用的是这个方法
跨域问题解决
var script=document.createElement('script');
script.type = 'text/javascript';
script.src = ur;
document.head.appendChild(script);
function onBack(res) {
alert(JSON.stringify(res));
}
还是刚刚的那个博客里面介绍的script直接访问的方法,亲测有效,但是为什么我最后还是没有用呢?这里又有一个 坑,也是我最后没有解决的坑。
最后没有解决的坑
Refused to execute script from ‘https://lightapp.weishao.com.cn/api/score/scoredata/find?xn=2017&xq=1&schcode=swust&stucode=5120170586&time=1532073315868’ because its MIME type (‘application/json’) is not executable, and strict MIME type checking is enabled.
这就是报错信息,没有解决。
4、结语
虽然过程比较艰辛,然后查阅了无数个文档,但是结果还是很不错的,也算是我自己第一个很成功的界面把。还是祭奠那些踩过的坑,还有某何大哥跟我说的习惯一定要好。嗯,就这些了。