自制的简易PHP更新公网IP脚本,有需要的自取!
不要问我这个能干嘛,懂的自然懂,不懂得我也懒得解释那么多,存在一定是合理的;
代码分享
<?php
/**
* 激活后可以跨域调用
*/
function allowCors()
{
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
}
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
}
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
exit(0);
}
}
// 允许跨域
allowCors();
/**
* 返回数据
* @param null $code
* @param null $msg
* @param null $data
*/
function returnJson($code = null, $msg = null, $data = null)
{
header("Content-type: application/json");
$result = ["code" => $code, "msg" => $msg, "data" => $data];
foreach ($result as $key => $value) {
if (empty($value)) unset($result[$key]);
}
echo json_encode($result,JSON_UNESCAPED_UNICODE);
exit();
}
// 配置信息
$config = [
"tokenFile" => "token.key",
"tokenAlgo" => "sha256",
"ipFile" => "ip.info",
"ipFormat" => "Y年m月d日 H:i:s"
];
// 获取参数
$action = $_GET["action"];
$token = $_GET["token"];
// 判断操作
switch ($action) {
case "install":
// 如果秘钥文件已存在,则不会继续创建
if (file_exists($config["tokenFile"])) {
returnJson(500, "秘钥文件已存在!不可重复安装!");
}
// 生成秘钥
$token = hash($config["tokenAlgo"], md5(microtime(true)));
// 写秘钥文件
file_put_contents($config["tokenFile"], $token);
// 返回秘钥信息
returnJson(200, "秘钥仅显示一次!请自行保存!", $token);
break;
case "update":
// 检查是否传了令牌
if (empty($token)) {
returnJson(401, "更新IP信息需要携带令牌!您尚携带令牌信息!请检查!");
}
// 校验令牌是否可用
if (file_get_contents($config["tokenFile"]) !== $token) {
returnJson(401, "令牌校验不通过!请检查您的令牌是否与服务器上令牌一致");
}
// 组装IP信息
$ipInfo = [
"ip" => $_SERVER["REMOTE_ADDR"],
"update_time" => time(),
"format_update_time" => date($config["ipFormat"], time()),
];
// 写本地文件
file_put_contents($config["ipFile"], json_encode($ipInfo));
// 返回结果
returnJson("IP地址信息已更新!", $ipInfo);
break;
default:
// 检查IP信息是否存在
if (!file_exists($config["ipFile"])) returnJson(500, "IP地址信息尚未更新,请稍后再试!");
// 返回结果
returnJson(200, "获取IP信息成功", json_decode(file_get_contents($config["ipFile"]), true));
break;
}
使用方式
- 实际操作中请将
https://example.ml
换成你自己的域名! - 接口请求方式一律为
GET
安装
接口参数
- action - 定值,填
install
示例调用
curl https://example.ml/index.php?action=install
返回内容
{
"code": 200,
"msg": "秘钥仅显示一次!请自行保存!",
"data": "bd17cf2d3f14ae53bcd5c21a24cc5454f0f52d5a9591d2e0275debd8641765e3"
}
更新IP
接口参数
- action - 定值,填
update
- token - 填写 安装 中获取到的令牌
示例调用
curl https://example.ml/index.php?action=update&token=bd17cf2d3f14ae53bcd5c21a24cc5454f0f52d5a9591d2e0275debd8641765e3
返回预览
{
"code": "IP地址信息已更新!",
"msg": {
"ip": "60.168.244.239",
"update_time": 1650553426,
"format_update_time": "2022年04月21日 23:03:46"
}
}
获取地址
如需获取地址,则无需传入任何参数,直接访问脚本即可
示例调用
curl https://example.ml/index.php
返回预览
{
"code": 200,
"msg": "获取IP信息成功",
"data": {
"ip": "60.168.244.239",
"update_time": 1650553426,
"format_update_time": "2022年04月21日 23:03:46"
}
}
附赠前端模板
预览地址见:https://example.ml
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-clipboard2@0.3.3/dist/vue-clipboard.min.js"></script>
<script src="https://unpkg.com/axios@0.26.1/dist/axios.min.js"></script>
<script src="https://unpkg.com/element-ui@2.15.8/lib/index.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui@2.15.8/lib/theme-chalk/index.css">
<style type="text/css">
html {
font-size: 15px;
}
body {
margin: 0;
background: #232526; /* fallback for old browsers */
background: -webkit-linear-gradient(to top, #414345, #232526); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to top, #414345, #232526); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
@media screen and (min-width: 768px) {
html {
font-size: 20px;
}
}
@media screen and (min-width: 992px) {
html {
font-size: 25px;
}
}
@media screen and (min-width: 1200px) {
html {
font-size: 40px;
}
}
#app {
height: 100vh;
width: 100vw;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
color: #fff;
}
h1.title {
font-size: 2rem;
margin: 0;
font-weight: normal;
}
button.ip {
color: #fff;
font-weight: bolder;
cursor: pointer;
outline: none;
line-height: 1em;
height: 1em;
font-size: 3rem;
background-color: transparent;
margin: 2rem 0;
border-width: 0 0 1px 0;
border-style: solid;
border-color: transparent;
}
button.ip:hover {
border-color: #ffffff;
}
p.info {
margin: 0;
font-size: 1rem;
font-weight: lighter;
}
.el-message {
font-size: 16px;
min-width: auto;
}
</style>
<title>获取最新公网IP地址</title>
</head>
<body>
<div id="app" v-cloak>
<h1 class="title">最新公网IP</h1>
<button class="ip"
v-clipboard:copy="ajaxReturn.ip"
v-clipboard:success="handleCopySuccess"
v-clipboard:error="handleCopyError">{{ ajaxReturn.ip || "-" }}
</button>
<p class="info">同步时间:{{ ajaxReturn.format_update_time || "-" }}</p>
</div>
<script>
const app = new Vue({
el: "#app",
data() {
return {
ajaxReturn: {}
}
},
created() {
this.init();
},
methods: {
/**
* 初始化数据
* @returns {Promise<void>}
*/
async init() {
const loading = this.$loading({
lock: true,
text: '同步中,请稍后'
});
const ajaxReturn = await this.syncIpAddress();
this.ajaxReturn = ajaxReturn;
loading.close();
this.$notify({
title: "同步成功",
message: "最新IP地址为:" + ajaxReturn.ip,
type: "success"
});
},
/**
* 同步IP地址数据
* @returns {Promise<unknown>}
*/
syncIpAddress() {
return new Promise((resolve, reject) => {
axios.get("api.php").then((xhr) => {
resolve(xhr.data.data);
}).catch(reject)
})
},
/**
* 复制成功
*/
handleCopySuccess() {
this.$notify({
title: "复制成功",
message: "IP地址已复制!快去使用吧!",
type: "success"
});
},
/**
* 复制失败
*/
handleCopyError() {
this.$notify({
title: "复制失败",
message: "当前浏览器不支持复制!建议更换主流浏览器或手动复制所需内容!",
type: "error"
});
}
}
})
</script>
</body>
</html>