最近学习的一些内容,包括跨域问题及其解决方案,安卓开发的简单探索,OpenAI的api做了个小插件
额,把原来用Hexo托管在Github上的博客重新搞了一下,本来我是想坚持每天写博客的,但一直苦于没有时间(其实就是懒),腾出时间把服务器和备案给搞了(又找借口),本来想用Vue和Spring自己写的,但还没学完( )
一、跨域问题及其解决方案
1.概念
跨域问题是指在浏览器的同源策略下,不同域名、端口或协议之间的网页请求受到限制,导致某些跨域请求被浏览器阻止。同源策略是一种安全机制,防止恶意网站获取到用户的敏感信息。
源:协议+域名+端口
- 不同域名:比如从
domain1.com 发起请求到 domain2.com。
- 不同端口:比如从
domain.com:3000 发起请求到 domain.com:4000。
- 不同协议:比如从
http://domain.com 发起请求到 https://domain.com。
2.解决方案
- CORS(跨域资源共享):服务器端设置响应头,允许特定来源的请求。通过设置
Access-Control-Allow-Origin 头部来指定允许访问的域名,但是建议不要设置 Access-Control-Allow-Origin: *,在某些情况下只设置通配符会被理解为暂未配置。
比如使用nodejs处理一个简单的请求
1 2 3 4 5 6
| const express = require('express'); const app = express(); app.get('/', (req, res) => { res.header('Access-Control-Allow-Origin', '127.0.0.1'); res.status(200).sendFile('XXX.html'); });
|
此时你能够在浏览器开发人员工具——网络选项卡看到这个响应头的一部分
这里注意,是只有在响应头中看到这段语句浏览器才能正常请求,找不到语句(没有默认是拒绝)或者没有请求所在的域名均不会成功
- JSONP(JSON with Padding):通过
<script> 标签的方式实现跨域请求。JSONP利用了 <script> 标签可以跨域加载的特性,不过只支持GET请求,并且存在安全性问题。
是早期的工程师们的非常天才的想法!这东西的原理是请求URL会返回类似callbackFunction(data)的字段,也就是一段js代码,这样可以使浏览器执行,从而实现预期效果
1 2 3 4
| <script src="https://otherdomain.com/data?callback=myFunction"></script> function myFunction(data) { console.log(data); }
|
- 代理服务器:在同源策略下,通过在同一个域名下创建API代理,让客户端请求自己的服务器,再由服务器转发请求到目标地址。这样可以绕过浏览器的限制。
1 2 3 4 5 6 7
| const resp = await axios.get('https://pvp.qq.com/web2 herolist.json');
app.get('/', (req, res) => { res.header('Access-Control-Allow-Origin', '127.0.0.1'); res.send(resp.data); });
|
二、安卓开发的浅探索
这个其实是一个迫不得已的学习内容,起因是班级同学拽上我去参加一个嵌入式比赛,作品当然是大一专属的小车(蚌埠住了),他们希望亮点是软件,所以我就现学的安卓开发,本来还学了Kotlin一瘸一拐地写了点内容,但后来搞一些复杂的内容用一个不熟悉的语言还是太痛苦,所以还是回到了Java
GitHub
grtsinry43/stm32-project-smartcontrol
项目包括以下几个类:
- MainActivity.java:应用的主界面,实现手动控制,扫码反序列化,关于页面等功能
- BluetoothActivity.java:实现蓝牙的连接和通信
- ControlActivity.java:实现小车的控制指令的发送和接收
- QRCodeActivity.java:实现二维码的扫描和解析
- AboutActivity.java:显示应用的相关信息
所有都是现学的,我就大概说一下我学到了什么吧:
安卓开发是标准舒服的行为样式相分离,开发的单位是Java/Kotlin的类,每个界面是Activity,每个图形元素有对应的xml样式布局文件。大体上开发时候先用Adobe XD或者sigma(国内也可以即时设计啥的)设计好界面,然后为每个元素写xml文件,Activity里面通过id找到元素,可以添加、修改元素,可以监听元素动作(比如Button),但是通知线程服务啥的必须得学明白,别像我啥都不会,写的时候很痛苦
三、OpenAI的api简单使用
就是用js调用一个api,把回应显示出来,没什么复杂的,现在以我的技术只能做出这样(捂脸),前端有太多需要学的了……
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
(function() { 'use strict';
var tooltip = document.createElement('div'); tooltip.style.position = 'fixed'; tooltip.style.zIndex = '9999'; tooltip.style.display = 'none'; tooltip.innerHTML = '<button id="gpt-answer">GPT回答</button>';
var answerArea = document.createElement('div'); answerArea.style.position = 'fixed'; answerArea.style.zIndex = '9999'; answerArea.style.display = 'none'; answerArea.style.outline = '1px solid';
document.body.appendChild(tooltip); document.body.appendChild(answerArea);
document.addEventListener('mouseup', function(e) { var selectedText = window.getSelection().toString().trim(); if (selectedText) { var selectedElement = window.getSelection().anchorNode.parentNode; var rect = selectedElement.getBoundingClientRect(); tooltip.style.left = (rect.right + 10) + 'px'; tooltip.style.top = rect.top + 'px'; tooltip.style.display = 'block'; } else { tooltip.style.display = 'none'; } });
document.getElementById('gpt-answer').addEventListener('click', function() { var selectedText = window.getSelection().toString().trim(); if (selectedText) { fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer API_KEY' }, body: JSON.stringify({ model: "gpt-3.5-turbo", messages: [ {"role": "system", "content": "你是一个耐心回答问题的助手,请解答这个问题,谢谢!"}, {"role": "user", "content": selectedText} ] }) }).then(response => response.json()) .then(data => { var gptResponse = data['choices'][0]['message']['content']; answerArea.textContent = gptResponse; var selectedElement = window.getSelection().anchorNode.parentNode; var rect = selectedElement.getBoundingClientRect(); answerArea.style.left = (rect.right + 10) + 'px'; answerArea.style.top = (rect.bottom + 10) + 'px'; answerArea.style.display = 'block'; }); } });
document.addEventListener('click', function(e) { if (e.target !== answerArea && e.target !== tooltip && e.target !== document.getElementById('gpt-answer')) { answerArea.style.display = 'none'; } }); })();
|
条评论