首页
统计
邻居
留言
关于
Search
1
彩虹商城系统开发API文档
4,323 阅读
2
IntelliJ IDEA 报错TextMate bundle load error: Bundle kotlin can't be registered
3,743 阅读
3
使用RaiDrive将网盘映射为本地磁盘
2,174 阅读
4
谷歌浏览器 Google Chrome 69.0.3497.100 正式稳定版、测试版及开发版本大全
2,131 阅读
5
抖音、小红书、快手 免费三网解析去水印小工具
2,044 阅读
精选推荐
源码分享
软件下载
影视资源
经验教程
模板插件
Emlogo
Wordpress
浮夸小生。
情感杂文
趣味生活
影视后期
Java学习笔记
登录
Search
标签搜索
个人分享
Wordpress
浮夸小生。
Wordpress教程
Java
PHP
Wordpress优化
Java笔记
网络技巧
网站
CDN
Windows
又拍云
教程
浏览器
IntelliJ IDEA
html
建站教程
微信
情感杂文
浮夸小生。
累计撰写
83
篇文章
累计收到
220
条评论
首页
栏目
精选推荐
源码分享
软件下载
影视资源
经验教程
模板插件
Emlogo
Wordpress
浮夸小生。
情感杂文
趣味生活
影视后期
Java学习笔记
页面
统计
邻居
留言
关于
搜索到
35
篇与
经验教程
的结果
2024-08-27
vue 在苹果IOS系统中调用微信扫一扫 按钮双击多次 或 重复调用多次才会生效
在vue中开发微信扫一扫功能,之前已经给过相应教程。其中点击按钮唤醒微信原生扫一扫功能,按钮需要双击才会生效。阅读官网文档后发现调用微信js要等待jssdk加载完成,放到wx.ready里面试一下。在配置文件加载完成后,调用wx.ready()方法,例如: wx.ready(function() { // 执行业务逻辑 // 例如调用JS-SDK接口等 });
2024年08月27日
34 阅读
0 评论
0 点赞
2023-12-03
长江雨课堂刷课原理分析记录-python脚本技
前言 本篇文章仅限于技术交流-请勿用于商业用途。(如有侵权请联系我,24小时内删除该文章) 起因:高中好哥们(假小子->变大美女)问我长江雨课堂能不能shua课???? emmm...这真不好拒绝,直接抓包分析!!!视频 通过浏览器发包分析 存在心跳包 每五秒一次,接口 以及 发包参数如下:#接口: https://changjiang.yuketang.cn/video-log/heartbeat/ #发包参数: 'heart_data': [ { 'i': 5, #常量 'et': 'playing', #播放操作 'p': 'web', #常量 'n': 'ali-cdn.xuetangx.com',#常量 'lob': 'ykt',# 常量 'cp': videoTime, # 播放进度 ->>>>>>>模拟生成 'fp': 0, # 常量 'tp': videoTime, # 视频时长 'sp': 1,# 常量 'ts': int(time.time() * 1000), # 时间戳 13位 我这里用python直接模拟的 'u': u,# user_id 'uip': '',# 常量 'c': c,# course_id 'v': v,# 视频id 'skuid': skuid, # skuid 'classroomid': classroomid, #classroom_id 'cc': cc, # 常量 'd': duration, # 视频时常 'pg': pg, #视频id + 随机字符串 可以写死 'sq': 2, # 常量 't': 'video', # 常量 'cards_id': 0, # 常量 'slide': 0, # 常量 'v_url': '', # 常量 } ] #以上视频参数 可以在以下接口获取参数值: https://changjiang.yuketang.cn/c27/online_courseware/xty/kls/pub_news/'+课件id+'/ #课件id的值通过该元素获取courseware_idpython代码目前只完成了 视频代码部分(默认是全部课程都刷->按顺序刷课)我没有学过python,代码很烂 勿喷import json import time import random import re import requests #cookies 填写自己的即可 cookies = {} # 课程列表 def course_list(): headers = { 'authority': 'changjiang.yuketang.cn', 'accept': 'application/json, text/plain, */*', 'accept-language': 'zh-CN,zh;q=0.9', 'cache-control': 'no-cache', 'pragma': 'no-cache', 'referer': 'https://changjiang.yuketang.cn/v2/web/index', 'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'university-id': '0', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', 'uv-id': '0', 'xt-agent': 'web', 'xtbz': 'ykt', } params = { 'identity': '2', } response = requests.get('https://changjiang.yuketang.cn/v2/api/web/courses/list', params=params, cookies=cookies, headers=headers) return response.text ## 访问课程链接 def course_info(course_id): headers = { 'authority': 'changjiang.yuketang.cn', 'accept': 'application/json, text/plain, */*', 'accept-language': 'zh-CN,zh;q=0.9', 'cache-control': 'no-cache', 'classroom-id': '14037619', # 'cookie': 'JG_fcdf8e635093adde6bef42651_PV=1701342457885|1701342464783; django_language=zh-cn; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMThjMWY3MTE4MzAxNmQ2LTBjZTM0NjRkYWQ4YmQ1OC0xNjUyNTYzNC0yMDczNjAwLTE4YzFmNzExODMxMjZhNyJ9%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%22%2C%22value%22%3A%22%22%7D%2C%22%24device_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%7D; sajssdk_2015_cross_new_user=1; csrftoken=kWczx89mCJgThyBIBlOitizxRIH7Tuef; sessionid=byzyzsb66yxmrf0vy702ap05mm88i74d; user_role=-1; classroomId=14037619; classroom_id=14037619; JG_fcdf8e635093adde6bef42651_PV=1701342457656|1701342457656', 'pragma': 'no-cache', 'referer': 'https://changjiang.yuketang.cn/v2/web/studentLog/14037619', 'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'university-id': '2868', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', 'uv-id': '2868', 'xt-agent': 'web', 'xtbz': 'ykt', } params = { 'actype': '-1', 'page': '0', 'offset': '20', 'sort': '-1', } response = requests.get( 'https://changjiang.yuketang.cn/v2/api/web/logs/learn/'+str(course_id), params=params, cookies=cookies,headers=headers) return response.text def courseware(id): headers = { 'authority': 'changjiang.yuketang.cn', 'accept': 'application/json, text/plain, */*', 'accept-language': 'zh-CN,zh;q=0.9', 'cache-control': 'no-cache', 'classroom-id': '14037619', # 'cookie': 'django_language=zh-cn; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMThjMWY3MTE4MzAxNmQ2LTBjZTM0NjRkYWQ4YmQ1OC0xNjUyNTYzNC0yMDczNjAwLTE4YzFmNzExODMxMjZhNyJ9%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%22%2C%22value%22%3A%22%22%7D%2C%22%24device_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%7D; sajssdk_2015_cross_new_user=1; csrftoken=kWczx89mCJgThyBIBlOitizxRIH7Tuef; sessionid=byzyzsb66yxmrf0vy702ap05mm88i74d; user_role=-1; classroomId=14037619; classroom_id=14037619; JG_fcdf8e635093adde6bef42651_PV=1701342457656|1701342457656', 'pragma': 'no-cache', 'referer': 'https://changjiang.yuketang.cn/v2/web/studentLog/14037619', 'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'university-id': '2868', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', 'uv-id': '2868', 'x-csrftoken': 'kWczx89mCJgThyBIBlOitizxRIH7Tuef', 'xt-agent': 'web', 'xtbz': 'ykt', } response = requests.get( 'https://changjiang.yuketang.cn/c27/online_courseware/xty/kls/pub_news/'+id+'/', cookies=cookies, headers=headers, ) return response.text def coursePageInfo(course_id, id): headers = { 'authority': 'changjiang.yuketang.cn', 'accept': 'application/json, text/plain, */*', 'accept-language': 'zh-CN,zh;q=0.9', 'cache-control': 'no-cache', 'classroom-id': '14037619', # 'cookie': 'django_language=zh-cn; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMThjMWY3MTE4MzAxNmQ2LTBjZTM0NjRkYWQ4YmQ1OC0xNjUyNTYzNC0yMDczNjAwLTE4YzFmNzExODMxMjZhNyJ9%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%22%2C%22value%22%3A%22%22%7D%2C%22%24device_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%7D; sajssdk_2015_cross_new_user=1; csrftoken=kWczx89mCJgThyBIBlOitizxRIH7Tuef; sessionid=byzyzsb66yxmrf0vy702ap05mm88i74d; user_role=-1; classroomId=14037619; classroom_id=14037619; JG_fcdf8e635093adde6bef42651_PV=1701342457656|1701342457656', 'pragma': 'no-cache', 'referer': 'https://changjiang.yuketang.cn/v2/web/xcloud/video-student/14037619/18867446', 'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'university-id': '2868', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', 'uv-id': '2868', 'xt-agent': 'web', 'xtbz': 'ykt', } response = requests.get( 'https://changjiang.yuketang.cn/mooc-api/v1/lms/learn/leaf_info/'+str(course_id)+'/'+str(id)+'/', cookies=cookies, headers=headers, ) return response.text def is_course_success(course_id, user_id, classroom_id, video_id): headers = { 'authority': 'changjiang.yuketang.cn', 'accept': 'application/json, text/plain, */*', 'accept-language': 'zh-CN,zh;q=0.9', 'cache-control': 'no-cache', 'classroom-id': '14037619', # 'cookie': 'django_language=zh-cn; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMThjMWY3MTE4MzAxNmQ2LTBjZTM0NjRkYWQ4YmQ1OC0xNjUyNTYzNC0yMDczNjAwLTE4YzFmNzExODMxMjZhNyJ9%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%22%2C%22value%22%3A%22%22%7D%2C%22%24device_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%7D; csrftoken=kWczx89mCJgThyBIBlOitizxRIH7Tuef; sessionid=byzyzsb66yxmrf0vy702ap05mm88i74d; user_role=-1; classroomId=14037619; classroom_id=14037619; JG_fcdf8e635093adde6bef42651_PV=1701342457656|1701342457656', 'pragma': 'no-cache', 'referer': 'https://changjiang.yuketang.cn/v2/web/xcloud/video-student/14037619/18867444', 'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'university-id': '2868', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', 'uv-id': '2868', 'xt-agent': 'web', 'xtbz': 'ykt', } params = { 'cid': course_id, 'user_id': user_id, 'classroom_id': classroom_id, 'video_type': 'video', 'vtype': 'rate', 'video_id': video_id, 'snapshot': '1', } response = requests.get( 'https://changjiang.yuketang.cn/video-log/get_video_watch_progress/', params=params, cookies=cookies, headers=headers, ) return response.text def shuake(duration, videoTime, u, c,v,skuid,classroomid,cc, pg): headers = { 'authority': 'changjiang.yuketang.cn', 'accept': '*/*', 'accept-language': 'zh-CN,zh;q=0.9', 'cache-control': 'no-cache', 'classroom-id': '14037619', 'content-type': 'application/json', # 'cookie': 'django_language=zh-cn; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMThjMWY3MTE4MzAxNmQ2LTBjZTM0NjRkYWQ4YmQ1OC0xNjUyNTYzNC0yMDczNjAwLTE4YzFmNzExODMxMjZhNyJ9%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%22%2C%22value%22%3A%22%22%7D%2C%22%24device_id%22%3A%2218c1f71183016d6-0ce3464dad8bd58-16525634-2073600-18c1f71183126a7%22%7D; sajssdk_2015_cross_new_user=1; csrftoken=kWczx89mCJgThyBIBlOitizxRIH7Tuef; sessionid=byzyzsb66yxmrf0vy702ap05mm88i74d; user_role=-1; classroomId=14037619; classroom_id=14037619; JG_fcdf8e635093adde6bef42651_PV=1701342457656|1701342457656', 'origin': 'https://changjiang.yuketang.cn', 'pragma': 'no-cache', 'referer': 'https://changjiang.yuketang.cn/v2/web/xcloud/video-student/14037619/18867447', 'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"macOS"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', 'x-csrftoken': 'kWczx89mCJgThyBIBlOitizxRIH7Tuef', 'x-requested-with': 'XMLHttpRequest', 'xtbz': 'ykt', } json_data = { 'heart_data': [ { 'i': 5, 'et': 'playing', 'p': 'web', 'n': 'ali-cdn.xuetangx.com', 'lob': 'ykt', 'cp': videoTime, 'fp': 0, 'tp': videoTime, 'sp': 1, 'ts': int(time.time() * 1000), 'u': u, 'uip': '', 'c': c, 'v': v, 'skuid': skuid, 'classroomid': classroomid, 'cc': cc, 'd': duration, 'pg': pg, 'sq': 2, 't': 'video', 'cards_id': 0, 'slide': 0, 'v_url': '', } ] } response = requests.post('https://changjiang.yuketang.cn/video-log/heartbeat/', cookies=cookies, headers=headers, json=json_data) if __name__ == '__main__': json_str = course_list() data = json.loads(json_str) course_lst= data['data']['list'] ## 遍历课程 刷课 for course_lst in course_lst: ## 获取课程id 全部刷 course_id = course_lst['classroom_id'] # 假设course_info()方法返回的是一个JSON字符串 json_str = course_info(course_id) # 解析JSON字符串为Python对象 data = json.loads(json_str) activities = data['data']['activities'] # 遍历JSON对象 for activity in activities: if 'type' in activity: type = activity['type'] # 公告 if type == 9: print('这是一个公告') pass # 期末测试 elif type == 20: print('这是期末测试') pass elif type == 15: # 全部单元Id courseware_id = activity['courseware_id'] json_str = courseware(courseware_id) data = json.loads(json_str) content_info = data['data']['content_info'] for content_info in content_info: print(content_info['name']) for section_list in content_info['section_list']: time.sleep(1) randomStr = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=6)) courseChapterId = section_list['leaf_list'][0]['id'] # 注意这个位置 可能有的页面有多个任务而被忽略 video_name = section_list['name'] print(video_name, courseChapterId) # 进入课程界面 json_str = coursePageInfo(course_id, courseChapterId) data = json.loads(json_str) videoInfo = data['data'] c = videoInfo['course_id'] cc = videoInfo['content_info']['media']['ccid'] classroomid = videoInfo['classroom_id'] # cp 播放时长 d = videoInfo['content_info']['media']['duration'] sku_id = videoInfo['sku_id'] pg = str(videoInfo['id']) + "_" + randomStr v = videoInfo['id'] u = videoInfo['user_id'] progress = is_course_success(c, u, classroomid, v) if_completed = '0' try: if_completed = re.search(r'"completed":(.+?),', progress).group(1) except: pass if if_completed == '1': print(video_name, '\033[31m学习完成,跳过\033[0m') continue else: print(video_name + ",尚未学习,现在开始自动学习") videoTime = 0 while True: if videoTime >= d: videoTime == d shuake(d, videoTime, u, c, v, sku_id, classroomid, cc, pg) print(video_name, '\033[31m学习完成\033[0m') break # 模拟每5秒递增5,实际应用时需要替换为实际的递增逻辑 videoTime += 5 # 判断当前播放时长是否超过视频总时长 # 发送心跳请求 shuake(d, videoTime, u, c, v, sku_id, classroomid, cc, pg) print('学习时长:', videoTime) time.sleep(5) else: pass
2023年12月03日
375 阅读
0 评论
0 点赞
2023-11-05
TypeError: Cannot read properties of undefined (reading 'validate') ——vue-Element
问题每一次都会犯相同的错误this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } });表单校验 报错 TypeError: Cannot read properties of undefined (reading 'validate') ——vue-Element.....只需要在 form标签上添加 :ref ="" ------完美解决<el-form :ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
2023年11月05日
328 阅读
0 评论
0 点赞
2023-06-27
vue + axios get 请求header后出现跨域错误
this.$axios({ method: "get", url: "http://localhost:8080/api/user/selectAll", headers: { token: this.$store.state.token }, })当我们写前后分离项目的时候需要添加拦截器需要配置token,配置好之后就会如下,出现跨域问题,明明什么都对,但就是找不到问题所在,后来我通过百度发现问题所在当我们在自定义请求头的时候,浏览器浏览器会根据需要,发起一个“PreFlight”(也就是Option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源,或者域) 这里请求头里也是有咱们写的请求头 但是在浏览器中运行就会报跨域异常 这就要说到OPTIONS如果自定义了请求头跨域请求就会变成复杂请求跨域请求有分为简单请求和复杂请求;一般情况下在不添加请求头的时候是简单请求,如果添加了话就是复杂请求,在发出复杂请求的之前,就会出现一次OPTIONS请求。OPTIONS请求可以被称作一次嗅探请求,通过这个方法,客户端可以在采取具体的资源请求之前,决定对资源采取何种必要措施。由于我的问题出现在请求内容为json的时候,所以是复杂请求,提前进行了一次OPTIONS请求。这个OPTIONS请求中没有增加我们的Authorization请求头,所以就无法通过我们的网关,在网管的地方被拦截下来了,返回了401所以我们就要在后端的拦截器中添加如下代码 if(request.getMethod().equals(RequestMethod.OPTIONS.name())) { response.setHeader("Access-Control-Allow-Origin","*"); response.setHeader("Access-Control-Allow-Headers","*"); response.setHeader("Access-Control-Allow-Methods","*"); response.setHeader("Access-Control-Allow-Credentials","true"); response.setHeader("Access-Control-Max-Age","3600"); response.setStatus(HttpStatus.OK.value()); return true; }目前的项目中,不需要考虑的太复杂,简单处理就是放行OPTIONS请求。这是我自己在项目中实际遇到的问题,百度解决的.然后总结写的一篇文章有错误的地方请指出
2023年06月27日
133 阅读
0 评论
0 点赞
2023-06-19
MacOs利用Brew安装Jdk11
一:安装JDK171.安装openjdk172.把homebrew安装的openjdk17软链接到系统目录brew search jdk //搜索可以安装的jdk版本 brew install openjdk@11 //按自己需要选择 3.执行安装sudo ln -sfn $(brew --prefix)/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk 二:检查是否安装成功在Terminal中运行下面的命令查看Java安装版本,如正常显示Java版本信息则说明安装成功,如果显示command java not find 或者其它则说明没有安装成功java --version三:配置环境变量切到jdk的home文件cd /Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home首次创建配置,可以使用这个命令创建配置文件~touch .bash_profile然后使用以下命令打开配置文件open -e .bash_profile添加配置内容:注意路径JAVA_HOME="/Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home" export JAVA_HOME CLASS_PATH="$JAVA_HOME/lib" PATH=".$PATH:$JAVA_HOME/bin"四:完成配置1.完成配置:source .bash_profile2.输入echo $JAVA_HOME可以看到环境配置的路径 source .bash_profile //完成配置 echo $JAVA_HOME //检查配置
2023年06月19日
850 阅读
3 评论
0 点赞
2022-03-24
${pageContext.request.contextPath}获取绝对路径乱码问题,导致jsp页面获取不到静态资源
${pageContext.request.contextPath}获取绝对路径乱码问题问题 Maven搭建的SSM项目,jsp页面用${pageContext.request.contextPath}获取绝对路径,运行后页面获取不到静态资源。截图解决方法IDEA创建项目时web.xml中的头文件默认版本是2.3,需要改成3.0,如下所示。<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> </web-app>效果重新发布项目 可见。
2022年03月24日
489 阅读
0 评论
0 点赞
2022-03-23
关于${pageContext.request.contextPath}的理解(转载)
${pageContext.request.contextPath}是JSP取得绝对路径的方法,等价于<%=request.getContextPath()%> 。 也就是取出部署的应用程序名或者是当前的项目名称 比如我的项目名称是demo1在浏览器中输入为http://localhost:8080/demo1/a.jsp ${pageContext.request.contextPath}或<%=request.getContextPath()%>取出来的就是/demo1,而"/"代表的含义就是http://localhost:8080故有时候项目中这样写${pageContext.request.contextPath}/a.jsp绝对路径与相对路径的比较1)采用相对路径遇到的问题 相对路径固然比较灵活,但如果想复制页面内的代码却变得比较困难,因为不同的页面具有不同的相对路径,复制后必须修改每一个连接的路径。 如果页面被多于一个的页面所包含,那么被包含页面中的相对路径将是不正确的。 如果采用Struts的Action返回页面,那么由于页面路径与 Action路径不同,使得浏览器无法正确解释页面中的路径,如页面为/pages/cust/cust.jsp,图片所有目录为/images /title.gif,这时在/pages/cust/cust.jsp中的所用的路径为”http://images.cnblogs.com /title.gif”,但是如果某一个Action的Forward指向这个JSP文件,而这个Action的路径为/cust/manage.do, 那么页面内容中”http://images.cnblogs.com/title.gif”就不再指向正确的路径了。 解决以上问题似乎只有使用绝对路径了。2)采用绝对路径遇到的问题 随着不同的Web应用发布方式,绝对路径的值也不同。如Web应用发布为MyApp,则路径”/MyApp/images/title.gif”是正确的, 但发布为另一应用时如MyApp2,这个路径就不对了,也许这个情况比较少,但以default方式发布Web应用时以上绝对路径也不 同:”/images/title.gif”。二.解决方案1)采用绝对路径,但为了解决不同部署方式的差别,在所有非struts标签的路径前加${pageContext.request.contextPath},如原路径为: ”/images/title.gif”,改为“${pageContext.request.contextPath}/images/title.gif”。 代码” ${pageContext.request.contextPath}”的作用是取出部署的应用程序名,这样不管如何部署,所用路径都是正确的。缺点: 操作不便,其他工具无法正确解释${pageContext.request.contextPath}2) 采用相对路径,在每个JSP文件中加入base标签,如: <base href="http://${header['host']}${pageContext.request.contextPath}/pages/cust/relation.jsp" />这样所有的路径都可以使用相对路径。缺点: 对于被包含的文件依然无效。 真正使用时需要灵活应用1)和2),写出更加健壮的代码。 在使用的时候可以使 用${pageContext.request.contextPath},也同时可以使 用<%=request.getContextPath()%>达到同样的效果,同时,也可以 将${pageContext.request.contextPath},放入一个JSP文件中,将用C:set放入一个变量中,然后在用的时候用EL 表达式取出来。</pre><pre name="code" class="html"><c:set var="ctx" value="${pageContext.request.contextPath}" /> 内容仅供个人学习、记录使用,侵删
2022年03月23日
327 阅读
0 评论
0 点赞
2022-02-06
js按钮复选框选择 小Demo
全选,全部选,反选<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>按钮选择器</title> <style> table { margin-top: 200px; text-align: center; } tr, th { height: 50px; } div { margin-top: 50px; margin-left: 40%; } </style> </head> <body> <table border="1px" width="500px" cellspacing="0" align="center"> <caption><h2>学生表</h2></caption> <tr> <th><input type="checkbox" name="cb" id="fist_select"></th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>操作</th> </tr> <tr> <td><input type="checkbox" name="cb"></td> <td>1</td> <td>孔子</td> <td>男</td> <td>删除</td> </tr> <tr> <td><input type="checkbox" name="cb"></td> <td>1</td> <td>孔子</td> <td>男</td> <td>删除</td> </tr> <tr> <td><input type="checkbox" name="cb"></td> <td>1</td> <td>孔子</td> <td>男</td> <td>删除</td> </tr> <tr> <td><input type="checkbox" name="cb"></td> <td>1</td> <td>孔子</td> <td>男</td> <td>删除</td> </tr> </table> <div> <input type="button" id="selectall" value="全选"> <input type="button" id="noselectall" value="全不选"> <input type="button" id="unSelect" value="反选"> </div> <script> //浏览器对象加载完毕 window.onload= function() { //按钮点击事件 document.getElementById("selectall").onclick = function() { //获取所有的复选框按钮 var cbs = document.getElementsByName('cb'); //遍历数组 for (var i = 0; i < cbs.length; i++) { //checked 属性设置或返回 checkbox 是否应被选中。 //checkboxObject.checked=true|false //调用checked() 方法 cbs[i].checked = true; } } document.getElementById("noselectall").onclick = function() { var cbs = document.getElementsByName('cb'); for (var i = 0; i < cbs.length; i++) { cbs[i].checked = false; } } document.getElementById("unSelect").onclick = function() { var cbs = document.getElementsByName('cb'); for (var i = 0; i < cbs.length; i++) { cbs[i].checked = !cbs[i].checked; } } document.getElementById("fist_select").onclick = function() { var cbs = document.getElementsByName('cb'); for (var i = 0; i < cbs.length; i++) { cbs[i].checked = this.checked; } } } </script> </body> </html>预览地址:https://bltang.cc/demo/buttonCheckbox.html
2022年02月06日
230 阅读
0 评论
0 点赞
2021-11-30
[逆向]某校园跑软件签名算法分析
前言同学在群中分享某虚拟定位轻松跑步法。作为旁观者,萌生出模拟请求进行数据伪造来完成任务(老操作了,像骨灰盒自动参加赠楼这种)某校园跑软件其实要求还算可以,极限情况:50天、每天1公里5分钟;就是不太好坚持分析思路{x} 抓包,看请求是否有签名,没有就去第4步 {x} 检测安装包是否有壳,无壳就去第4步 {x} 脱壳 {x} 分析代码 {x} 伪造请求 {x} 等待正义的审判 ::(惊哭)一、先抓包(非重点,不过多赘述)token 理论上是用户标识appkey 肯定大部分时间为定值sign MD5签名二、查壳360加固,一般 #(cos滑稽)三、脱壳这里使用这个工具:CodingGay/BlackDex: BlackDex is an Android unpack(dexdump) tool, it supports Android 5.0~12 and need not rely to any environment. BlackDex can run on any Android mobile phone or emulator, you can unpack APK File in several seconds. (github.com) 下载32位版本安装包(因为,目标APP是32位的){message type="warning" content="顺便记下包名com.tanma.unirun"/}单击目标应用,开始脱壳四、分析目标“源码”位置打开脱壳后的dex文件所在目录,使用MT管理器 的 dex编辑器++ 打开搜索字符串 sign只看目标应用的包看包名:{x} entities 实体包,排除 {x} enums 枚举包,排除 {x} network.settings 网络设置包 且类名”MyInterceptor”与拦截相关, 大概率符合条件初步查看源码,在请求头中添加sign,肯定是这里了接下来,使用电脑进行具体签名流程分析了五、分析代码逻辑分析请看注释public final class MyInterceptor implements Interceptor { private static final String APPKEY = "389885588s0648fa"; private static final String APPSECRET = "56E39A1658455588885690425C0FD16055A21676"; private static final Charset ChartSet_UTF8 = Charset.forName("UTF-8"); public static final Companion Companion = new Companion((DefaultConstructorMarker) null); public MyInterceptor() { } static { } public Response intercept(Interceptor.Chain chain) { boolean z; String str; Request.Builder newBuilder; Request.Builder addHeader; Request.Builder addHeader2; Request.Builder newBuilder2; Request.Builder addHeader3; Request.Builder addHeader4; Request.Builder addHeader5; String str2; String str3; boolean z2; String str4; String str5; String str6; String str7; Set queryParameterNames; Interceptor.Chain chain2 = chain; Intrinsics.checkParameterIsNotNull(chain2, "chain"); Request request = chain.request(); // 注意,TreeSet是有序集合,且默认为正序排列,即{a, b, c, d [,...]} TreeSet treeSet = new TreeSet(); Request request2 = null; HttpUrl url = request != null ? request.url() : null; if (!(url == null || (queryParameterNames = url.queryParameterNames()) == null)) { treeSet.addAll(queryParameterNames); } // 待签名字符串 StringBuilder sb = new StringBuilder(); Iterator it = treeSet.iterator(); // 开始迭代所有请求参数 while (true) { z = false; if (!it.hasNext()) { break; } // str8 为参数名 String str8 = (String) it.next(); // 获取参数名对应的值 List queryParameterValues = url != null ? url.queryParameterValues(str8) : null; if (queryParameterValues != null && (true ^ queryParameterValues.isEmpty())) { // 参数值非空 // 取参数值列表第一个 String str9 = (String) (url != null ? url.queryParameterValues(str8) : null).get(0); if (!TextUtils.isEmpty(str9)) { // str8 参数名, str9 参数值 // str9非空,追加str8 str9在sb之后 sb.append(str8); sb.append(str9); } } } // 追加APPKEY sb.append("389885588s0648fa"); // 追加APPSECRET sb.append("56E39A1658455588885690425C0FD16055A21676"); if (request.body() != null) { BufferedSink buffer = new Buffer(); RequestBody body = request.body(); if (body != null) { body.writeTo(buffer); } Charset charset = ChartSet_UTF8; RequestBody body2 = request.body(); MediaType contentType = body2 != null ? body2.contentType() : null; if (contentType != null) { // 追加请求体 sb.append(buffer.readString(contentType.charset(charset))); } } // 同sb String sb2 = sb.toString(); Intrinsics.checkExpressionValueIsNotNull(sb2, "signStr.toString()"); CharSequence charSequence = sb2; if (!(charSequence == null || charSequence.length() == 0)) { // 本级语句块替换一些字符为空字符,即删除部分字符,这将导致参与MD5运算的字符串有所差异 // z2 为是否发生过替换操作 // 删除空格 if (StringsKt.contains$default(charSequence, " ", false, 2, (Object) null)) { str3 = StringsKt.replace$default(sb2, " ", "", false, 4, (Object) null); z2 = true; } else { str3 = sb2; z2 = false; } // 删除~ if (StringsKt.contains$default(str3, "~", false, 2, (Object) null)) { str4 = StringsKt.replace$default(str3, "~", "", false, 4, (Object) null); z2 = true; } else { str4 = str3; } // 删除! if (StringsKt.contains$default(str4, "!", false, 2, (Object) null)) { str5 = StringsKt.replace$default(str4, "!", "", false, 4, (Object) null); z2 = true; } else { str5 = str4; } // 删除( if (StringsKt.contains$default(str5, "(", false, 2, (Object) null)) { str6 = StringsKt.replace$default(str5, "(", "", false, 4, (Object) null); z2 = true; } else { str6 = str5; } // 删除) if (StringsKt.contains$default(str6, ")", false, 2, (Object) null)) { str7 = StringsKt.replace$default(str6, ")", "", false, 4, (Object) null); z2 = true; } else { str7 = str6; } // 删除' if (StringsKt.contains$default(str7, "'", false, 2, (Object) null)) { sb2 = StringsKt.replace$default(str7, "'", "", false, 4, (Object) null); z = true; } else { z = z2; sb2 = str7; } if (z) { sb2 = URLEncoder.encode(sb2, "utf-8"); Intrinsics.checkExpressionValueIsNotNull(sb2, "URLEncoder.encode(dealStr,\"utf-8\")"); } } if (z) { StringBuilder sb3 = new StringBuilder(); // 使用替换结果 sb2 计算MD5 String encodeByMD5 = MD5Digest.Companion.encodeByMD5(sb2); if (encodeByMD5 == null) { str2 = null; } else if (encodeByMD5 != null) { // 转换为大写 str2 = encodeByMD5.toUpperCase(); Intrinsics.checkExpressionValueIsNotNull(str2, "(this as java.lang.String).toUpperCase()"); } else { throw new TypeCastException("null cannot be cast to non-null type java.lang.String"); } sb3.append(str2); // MD5追加编码 sb3.append("encodeutf8"); str = sb3.toString(); } else { MD5Digest.Companion companion = MD5Digest.Companion; // 没有发生替换,使用sb String sb4 = sb.toString(); Intrinsics.checkExpressionValueIsNotNull(sb4, "signStr.toString()"); // 使用sb计算MD5 String encodeByMD52 = companion.encodeByMD5(sb4); if (encodeByMD52 == null) { str = null; } else if (encodeByMD52 != null) { // 转换为大写 str = encodeByMD52.toUpperCase(); Intrinsics.checkExpressionValueIsNotNull(str, "(this as java.lang.String).toUpperCase()"); } else { throw new TypeCastException("null cannot be cast to non-null type java.lang.String"); } } try { User user = (User) new PreUtil("sp_name_user").getValue("sp_user", Reflection.getOrCreateKotlinClass(User.class), (Object) null); if (user != null) { OauthTokenBean oauthToken = user.getOauthToken(); String token = oauthToken != null ? oauthToken.getToken() : null; Request request3 = chain.request(); if (!(request3 == null || (newBuilder2 = request3.newBuilder()) == null || (addHeader3 = newBuilder2.addHeader("token", token)) == null || (addHeader4 = addHeader3.addHeader("appKey", "389885588s0648fa")) == null || (addHeader5 = addHeader4.addHeader("sign", str)) == null) // 添加签名至头部 ) { request2 = addHeader5.build(); } } else { Request request4 = chain.request(); if (!(request4 == null || (newBuilder = request4.newBuilder()) == null || (addHeader = newBuilder.addHeader("appKey", "389885588s0648fa")) == null || (addHeader2 = addHeader.addHeader("sign", str)) == null)) { request2 = addHeader2.build(); } } Response proceed = chain2.proceed(request2); if (proceed == null) { Intrinsics.throwNpe(); } return proceed; } catch (Exception e) { e.printStackTrace(); Response proceed2 = chain2.proceed(request); if (proceed2 == null) { Intrinsics.throwNpe(); } return proceed2; } } }六、逻辑总结(经过验证){x} 将请求参数正序排序 {x} 将请求参数按 参数名1参数值1参数名2参数值2.... 拼接 {x} 追加appkey, 追加appsecret {x} 追加请求体 {x} 删除部分字符 {x} 计算MD5
2021年11月30日
488 阅读
0 评论
0 点赞
2021-09-17
Sublime text3编辑器 HTML快速生成代码 Tab无效快速解决方法
##安装Emmet
2021年09月17日
448 阅读
0 评论
0 点赞
1
2
...
4