插件介绍
外链跳转工具,具有可自定义的跳转页面和基本安全功能。
插件购买
首发优惠卷领取
推荐码
首发价过后,可使用本站推荐码进行购买,可享受一定折扣。
推荐码
springai
或者推荐链接
https://www.yunext.cn/store/apps?ref=springai
购买地址
本站同款模板
模板演示




模板使用方式
代码
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title th:text="|${site.title} - 外链跳转|"></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}
body {
background-color: #f8fafc;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
color: #1e293b;
}
.content {
background: white;
border-radius: 12px;
width: 100%;
max-width: 480px;
padding: 30px 20px;
text-align: center;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.03);
}
.title-logo {
margin-bottom: 20px;
}
.logo {
width: 70px;
height: 70px;
background: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
font-size: 28px;
color: #3b82f6;
}
h2 {
font-size: 20px;
font-weight: 600;
margin-bottom: 25px;
color: #1e293b;
line-height: 1.4;
}
.target-info {
background: #f1f5f9;
border-radius: 10px;
padding: 18px;
margin-bottom: 20px;
text-align: left;
}
.target-label {
font-size: 14px;
color: #64748b;
margin-bottom: 8px;
font-weight: 500;
display: flex;
align-items: center;
gap: 8px;
}
.target-url {
font-size: 15px;
color: #1e293b;
font-weight: 500;
word-break: break-all;
display: block;
padding: 6px 0;
line-height: 1.4;
}
.security-status {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
border-radius: 20px;
margin-bottom: 20px;
font-size: 13px;
font-weight: 500;
background: #f1f5f9;
}
.status-badge {
font-weight: 600;
padding: 4px 10px;
border-radius: 20px;
font-size: 12px;
}
.status-badge.https {
background: #dcfce7;
color: #16a34a;
}
.status-badge.http {
background: #fee2e2;
color: #dc2626;
}
.actions {
display: flex;
gap: 12px;
margin-bottom: 25px;
justify-content: center;
flex-wrap: wrap;
}
.btn {
padding: 12px 20px;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
border: none;
cursor: pointer;
transition: all 0.2s ease;
flex: 1;
min-width: 140px;
max-width: 100%;
}
.btn-primary {
background: #3b82f6;
color: white;
}
.btn-primary:hover {
background: #2563eb;
}
.btn-secondary {
background: #f1f5f9;
color: #475569;
}
.btn-secondary:hover {
background: #e2e8f0;
}
.checkbox-container {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
margin-bottom: 20px;
font-size: 13px;
color: #64748b;
}
.checkbox-container input[type="checkbox"] {
width: 16px;
height: 16px;
border-radius: 4px;
border: 1px solid #cbd5e1;
background: white;
cursor: pointer;
}
.link-countdown {
background: #f1f5f9;
border-radius: 10px;
padding: 16px;
margin-top: 8px;
}
#link-countdown-text {
display: block;
font-size: 14px;
color: #475569;
margin-bottom: 12px;
font-weight: 500;
}
.link-progress-bar {
height: 4px;
background: #e2e8f0;
border-radius: 3px;
overflow: hidden;
}
.link-progress-fill {
height: 100%;
width: 65%;
background: #3b82f6;
border-radius: 3px;
}
.security-tips {
margin-top: 20px;
font-size: 12px;
color: #64748b;
line-height: 1.6;
background: #fef3c7;
padding: 12px;
border-radius: 8px;
text-align: left;
display: flex;
align-items: flex-start;
gap: 8px;
}
.security-tips i {
color: #d97706;
margin-top: 2px;
}
@media (max-width: 768px) {
/* 手机端隐藏.picture内容 */
.picture {
display: none;
}
/* 调整内容区域宽度 */
main {
width: 100%;
max-width: 100%;
}
.content {
max-width: 100%;
padding: 25px 15px;
}
.actions {
flex-direction: column;
align-items: stretch;
gap: 10px;
}
.btn {
width: 100%;
min-width: auto;
}
h2 {
font-size: 18px;
margin-bottom: 20px;
}
.target-info {
padding: 15px;
}
.target-url {
font-size: 14px;
}
.checkbox-container {
font-size: 12px;
}
}
@media (max-width: 400px) {
.content {
padding: 20px 12px;
}
h2 {
font-size: 17px;
}
.target-url {
font-size: 13px;
}
.security-status {
font-size: 12px;
padding: 6px 12px;
}
}
</style>
<style>
.title-logo{
margin-bottom: 20px;
text-align: center;
}
.logo{
height: 60px;
width: auto;
max-width: 200px;
object-fit: contain;
}
</style>
<style>
/** Codepen: https://codepen.io/kdbkapsere/pen/oNXLbqQ */
:root {
--color-bg-primary: #fff;
--color-text-primary: #0e0620;
--color-ui-bg-primary: #0e0620;
--color-ui-bg-inverted: #fff;
}
@media (prefers-color-scheme: dark) {
:root {
--color-bg-primary: #212121;
--color-text-primary: #fafafa;
--color-ui-bg-primary: #fafafa;
--color-ui-bg-inverted: #212121;
}
}
html, body {
margin: 0;
padding: 0;
min-height: 100%;
height: 100%;
width: 100%;
background-color: var(--color-bg-primary);
color: var(--color-text-primary);
font-family: sans-serif;
font-size: 16px;
word-break: keep-all;
}
@media screen and (min-width: 2000px) {
html, body {
font-size: 20px;
}
}
body {
align-items: center;
display: flex;
justify-content: center;
height: 100%;
}
main {
width: 100%;
max-width: 1140px;
display: flex;
justify-content: space-between;
}
.picture, .content {
box-sizing: border-box;
width: 50%;
}
.content {
padding: 0 40px;
}
svg .dark {
stroke: var(--color-ui-bg-primary);
}
svg .fill-dark {
fill: var(--color-ui-bg-primary);
}
svg .fill-light {
fill: var(--color-ui-bg-inverted);
}
h1 {
font-size: 9em;
margin: 0.1em 0;
font-weight: bold;
}
h2 {
font-size: 2em;
font-weight: bold;
}
/* */
@media screen and (max-width: 768px) {
main {
display: block;
}
.picture, .content {
width: 100%;
text-align: center;
}
.content {
padding: 0 20px;
}
.picture svg {
max-width: 60%;
}
}
</style>
<style>
@keyframes moveAndRotate {
0% { transform: translateY(0) rotate(0); }
50% { transform: translateY(1px) rotate(1deg); }
100% { transform: translateY(0) rotate(0); }
}
svg #spaceman {
animation: moveAndRotate 2.5s ease-in-out infinite alternate;
}
@keyframes moveXLeft {
0%, 100% { transform: translateX(0); }
50% { transform: translateX(-3px); }
}
svg #craterSmall {
animation: moveXLeft 1.7s ease-in-out infinite alternate;
}
@keyframes moveXRight {
0%, 100% { transform: translateX(0); }
50% { transform: translateX(3px); }
}
svg #craterBig {
animation: moveXRight 2s ease-in-out infinite alternate;
}
@keyframes rotatePlanet {
0%, 100% { transform: rotate(0); }
50% { transform: rotate(-2deg); }
}
svg #planet {
animation: rotatePlanet 2.2s ease-in-out infinite alternate;
transform-origin: 70% 30%;
}
@keyframes rotateStars {
0%, 100% { transform: rotate(0); }
50% { transform: rotate(calc(0.8deg)); }
}
svg #starsBig g {
animation: rotateStars 1s ease-in-out infinite alternate;
transform-origin: 40% 60%;
}
@keyframes scaleStars {
0% { transform: scale(0.96); }
50% { transform: scale(1); }
100% { transform: scale(0.98); }
}
svg #starsSmall g {
animation: scaleStars 1.7s ease-in-out infinite alternate;
transform-origin: 50% 50%;
}
@keyframes moveYSmall {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-4px); }
}
svg #circlesSmall circle {
animation: moveYSmall 1.85s ease-in-out infinite alternate;
}
@keyframes moveYBig {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-3px); }
}
svg #circlesBig circle {
animation: moveYBig 2s ease-in-out infinite alternate;
}
svg #glassShine {
opacity: 0;
}
</style>
</head>
<body th:with="targetUrl = ${target},sourceUrl = ${ref},
isHttps = ${#strings.startsWith(targetUrl, 'https://')}">
<main>
<div class="picture">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
<g>
<defs>
<clipPath id="GlassClip">
<path d="M380.857,346.164c-1.247,4.651-4.668,8.421-9.196,10.06c-9.332,3.377-26.2,7.817-42.301,3.5
s-28.485-16.599-34.877-24.192c-3.101-3.684-4.177-8.66-2.93-13.311l7.453-27.798c0.756-2.82,3.181-4.868,6.088-5.13
c6.755-0.61,20.546-0.608,41.785,5.087s33.181,12.591,38.725,16.498c2.387,1.682,3.461,4.668,2.705,7.488L380.857,346.164z"></path>
</clipPath>
<clipPath id="cordClip">
<rect width="800" height="600"></rect>
</clipPath>
</defs>
<g id="planet">
<circle fill="none" stroke-width="3" stroke-miterlimit="10" cx="572.859" cy="108.803" r="90.788" class="dark"></circle>
<circle id="craterBig" fill="none" stroke-width="3" stroke-miterlimit="10" cx="548.891" cy="62.319" r="13.074" class="dark"></circle>
<circle id="craterSmall" fill="none" stroke-width="3" stroke-miterlimit="10" cx="591.743" cy="158.918" r="7.989" class="dark"></circle>
<path id="ring" fill="none" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" class="dark" d="M476.562,101.461c-30.404,2.164-49.691,4.221-49.691,8.007c0,6.853,63.166,12.408,141.085,12.408s141.085-5.555,141.085-12.408c0-3.378-15.347-4.988-40.243-7.225"></path>
<path id="ringShadow" opacity="0.5" fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" d="M483.985,127.43c23.462,1.531,52.515,2.436,83.972,2.436c36.069,0,68.978-1.19,93.922-3.149"></path>
</g>
<g id="stars">
<g id="starsBig">
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="518.07" y1="245.375" x2="518.07" y2="266.581"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="508.129" y1="255.978" x2="528.01" y2="255.978"></line>
</g>
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="154.55" y1="231.391" x2="154.55" y2="252.598"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="144.609" y1="241.995" x2="164.49" y2="241.995"></line>
</g>
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="320.135" y1="132.746" x2="320.135" y2="153.952"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="310.194" y1="143.349" x2="330.075" y2="143.349"></line>
</g>
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="200.67" y1="483.11" x2="200.67" y2="504.316"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="210.611" y1="493.713" x2="190.73" y2="493.713"></line>
</g>
</g>
<g id="starsSmall">
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="432.173" y1="380.52" x2="432.173" y2="391.83"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="426.871" y1="386.175" x2="437.474" y2="386.175"></line>
</g>
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="489.555" y1="299.765" x2="489.555" y2="308.124"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="485.636" y1="303.945" x2="493.473" y2="303.945"></line>
</g>
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="231.468" y1="291.009" x2="231.468" y2="299.369"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="227.55" y1="295.189" x2="235.387" y2="295.189"></line>
</g>
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="244.032" y1="547.539" x2="244.032" y2="555.898"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="247.95" y1="551.719" x2="240.113" y2="551.719"></line>
</g>
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="186.359" y1="406.967" x2="186.359" y2="415.326"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="190.277" y1="411.146" x2="182.44" y2="411.146"></line>
</g>
<g>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="480.296" y1="406.967" x2="480.296" y2="415.326"></line>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="484.215" y1="411.146" x2="476.378" y2="411.146"></line>
</g>
</g>
<g id="circlesBig">
<circle fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" cx="588.977" cy="255.978" r="7.952"></circle>
<circle fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" cx="450.066" cy="320.259" r="7.952"></circle>
<circle fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" cx="168.303" cy="353.753" r="7.952"></circle>
<circle fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" cx="429.522" cy="201.185" r="7.952"></circle>
<circle fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" cx="200.67" cy="176.313" r="7.952"></circle>
<circle fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" cx="133.343" cy="477.014" r="7.952"></circle>
<circle fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" cx="283.521" cy="568.033" r="7.952"></circle>
<circle fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" cx="413.618" cy="482.387" r="7.952"></circle>
</g>
<g id="circlesSmall">
<circle class="fill-dark" cx="549.879" cy="296.402" r="2.651"></circle>
<circle class="fill-dark" cx="253.29" cy="229.24" r="2.651"></circle>
<circle class="fill-dark" cx="434.824" cy="263.931" r="2.651"></circle>
<circle class="fill-dark" cx="183.708" cy="544.176" r="2.651"></circle>
<circle class="fill-dark" cx="382.515" cy="530.923" r="2.651"></circle>
<circle class="fill-dark" cx="130.693" cy="305.608" r="2.651"></circle>
<circle class="fill-dark" cx="480.296" cy="477.014" r="2.651"></circle>
</g>
</g>
<g id="spaceman">
<path id="cord" fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M273.813,410.969c0,0-54.527,39.501-115.34,38.218c-2.28-0.048-4.926-0.241-7.841-0.548c-68.038-7.178-134.288-43.963-167.33-103.87c-0.908-1.646-1.793-3.3-2.654-4.964c-18.395-35.511-37.259-83.385-32.075-118.817"></path>
<path id="backpack" class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M338.164,454.689l-64.726-17.353c-11.086-2.972-17.664-14.369-14.692-25.455l15.694-58.537c3.889-14.504,18.799-23.11,33.303-19.221l52.349,14.035c14.504,3.889,23.11,18.799,19.221,33.303l-15.694,58.537C360.647,451.083,349.251,457.661,338.164,454.689z"></path>
<g id="antenna">
<line class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="323.396" y1="236.625" x2="295.285" y2="353.753"></line>
<circle class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" cx="323.666" cy="235.617" r="6.375"></circle>
</g>
<g id="armR">
<path class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M360.633,363.039c1.352,1.061,4.91,5.056,5.824,6.634l27.874,47.634c3.855,6.649,1.59,15.164-5.059,19.02l0,0c-6.649,3.855-15.164,1.59-19.02-5.059l-5.603-9.663"></path>
<path class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M388.762,434.677c5.234-3.039,7.731-8.966,6.678-14.594c2.344,1.343,4.383,3.289,5.837,5.793c4.411,7.596,1.829,17.33-5.767,21.741c-7.596,4.411-17.33,1.829-21.741-5.767c-1.754-3.021-2.817-5.818-2.484-9.046C375.625,437.355,383.087,437.973,388.762,434.677z"></path>
</g>
<g id="armL">
<path class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M301.301,347.66c-1.702,0.242-5.91,1.627-7.492,2.536l-47.965,27.301c-6.664,3.829-8.963,12.335-5.134,18.999h0c3.829,6.664,12.335,8.963,18.999,5.134l9.685-5.564"></path>
<path class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M241.978,395.324c-3.012-5.25-2.209-11.631,1.518-15.977c-2.701-0.009-5.44,0.656-7.952,2.096c-7.619,4.371-10.253,14.09-5.883,21.71c4.371,7.619,14.09,10.253,21.709,5.883c3.03-1.738,5.35-3.628,6.676-6.59C252.013,404.214,245.243,401.017,241.978,395.324z"></path>
</g>
<g id="body">
<path class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M353.351,365.387c-7.948,1.263-16.249,0.929-24.48-1.278c-8.232-2.207-15.586-6.07-21.836-11.14c-17.004,4.207-31.269,17.289-36.128,35.411l-1.374,5.123c-7.112,26.525,8.617,53.791,35.13,60.899l0,0c26.513,7.108,53.771-8.632,60.883-35.158l1.374-5.123C371.778,395.999,365.971,377.536,353.351,365.387z"></path>
<path fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M269.678,394.912L269.678,394.912c26.3,20.643,59.654,29.585,93.106,25.724l2.419-0.114"></path>
</g>
<g id="legs">
<g id="legR">
<path class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M312.957,456.734l-14.315,53.395c-1.896,7.07,2.299,14.338,9.37,16.234l0,0c7.07,1.896,14.338-2.299,16.234-9.37l17.838-66.534C333.451,455.886,323.526,457.387,312.957,456.734z"></path>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="304.883" y1="486.849" x2="330.487" y2="493.713"></line>
</g>
<g id="legL">
<path class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M296.315,452.273L282,505.667c-1.896,7.07-9.164,11.265-16.234,9.37l0,0c-7.07-1.896-11.265-9.164-9.37-16.234l17.838-66.534C278.993,441.286,286.836,447.55,296.315,452.273z"></path>
<line fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="262.638" y1="475.522" x2="288.241" y2="482.387"></line>
</g>
</g>
<g id="head">
<ellipse transform="matrix(0.259 -0.9659 0.9659 0.259 -51.5445 563.2371)" class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" cx="341.295" cy="315.211" rx="61.961" ry="60.305"></ellipse>
<path id="headStripe" fill="none" class="dark" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M330.868,261.338c-7.929,1.72-15.381,5.246-21.799,10.246"></path>
<path class="dark fill-light" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M380.857,346.164c-1.247,4.651-4.668,8.421-9.196,10.06c-9.332,3.377-26.2,7.817-42.301,3.5s-28.485-16.599-34.877-24.192c-3.101-3.684-4.177-8.66-2.93-13.311l7.453-27.798c0.756-2.82,3.181-4.868,6.088-5.13c6.755-0.61,20.546-0.608,41.785,5.087s33.181,12.591,38.725,16.498c2.387,1.682,3.461,4.668,2.705,7.488L380.857,346.164z"></path>
<g>
<polygon id="glassShine" fill="none" class="dark" stroke-width="3" stroke-miterlimit="10" points="278.436,375.599 383.003,264.076 364.393,251.618 264.807,364.928 "></polygon>
</g>
</g>
</g>
</g>
</svg>
</div>
<div class="content">
<div class="title-logo" th:if="${redirectPage.displayOptions.showLogo && not #strings.isEmpty(site.logo)}">
<img th:src="${site.logo}" alt="Logo" class="logo">
</div>
<h2 th:text="${redirectPage.pageContent.pageTitle}"></h2>
<div class="target-info">
<div class="target-label" th:text="${redirectPage.pageContent.urlLabel}"></div>
<div class="target-url-container">
<span class="target-url" th:text="${targetUrl}"></span>
</div>
</div>
<div class="security-status" th:if="${redirectPage.displayOptions.showSecurityInfo}">
<span class="status-label">安全状态</span>
<span th:class="|status-badge ${isHttps ? 'https' : 'http'}|">[[${ isHttps ? 'HTTPS' : 'HTTP' }]]</span>
</div>
<div class="actions">
<button type="button" id="link-continue" class="btn btn-primary">[[${redirectPage.buttonSettings.buttonTextContinue}]]</button>
<button type="button" th:if="${redirectPage.displayOptions.showBackButton}" id="link-back" class="btn btn-secondary">[[${redirectPage.buttonSettings.buttonTextBack}]]</button>
</div>
<div class="checkbox-container" th:if="${redirectPage.displayOptions.showCookieDurationButton}">
<input type="checkbox" id="dontShowAgain">
<label for="dontShowAgain">[[${redirectPage.cookieDuration}]] 天内不显示此警告</label>
</div>
<div class="link-countdown" th:if="${redirectPage.autoRedirectEnabled && redirectPage.countdownSettings.redirectDelay > 0}">
<span id="link-countdown-text">[[${redirectPage.countdownSettings.countdownText}]]</span>
<div class="link-progress-bar" th:if="${redirectPage.countdownSettings.showProgressBar}">
<div class="link-progress-fill" id="progress-fill"></div>
</div>
</div>
<div class="security-tips">
<i class="fas fa-exclamation-circle"></i>请确保您信任此网站,外部链接可能包含不安全内容
</div>
</div>
</main>
<script type="text/javascript">
(function() {
var targetUrl = "[(${targetUrl})]";
var sourceUrl = "[(${sourceUrl})]";
var autoRedirectEnabled = [[${redirectPage.autoRedirectEnabled}]];
var countdown = [[${redirectPage.autoRedirectEnabled ? redirectPage.countdownSettings.redirectDelay : 0 }]];
var countdownElement = document.getElementById('link-countdown-text');
var progressElement = document.getElementById('progress-fill');
var continueButton = document.getElementById('link-continue');
var backButton = document.getElementById('link-back');
var noRedirectCheckbox = document.getElementById('dontShowAgain');
var countdownTemplate = "[(${redirectPage.countdownSettings.countdownText})]";
var initialCountdown = countdown;
var autoRedirectEnabled = autoRedirectEnabled ? 'true' : 'false';
// Enhanced back button functionality
function goBack() {
var referrer = document.referrer;
// Try multiple back strategies
if (referrer && referrer !== window.location.href) {
// If we have a valid referrer, go there
window.location.href = referrer;
} else if (sourceUrl && sourceUrl !== window.location.href) {
// If we have source URL from plugin, use it
window.location.href = sourceUrl;
} else if (window.history.length > 1) {
// Use browser history if available
window.history.back();
} else {
// Fallback to homepage
window.location.href = "[(${site.url})]";
}
}
if (backButton) {
backButton.addEventListener('click', function(e) {
goBack();
});
}
if (noRedirectCheckbox) {
noRedirectCheckbox.addEventListener('change', function() {
var cookieExpiry = new Date();
cookieExpiry.setDate(cookieExpiry.getDate() + [[${redirectPage.cookieDuration}]]);
document.cookie = "link_noredirect=" + (this.checked ? "1" : "0") +
"; expires=" + cookieExpiry.toUTCString() +
"; path=/; SameSite=Strict";
});
}
if (continueButton) {
continueButton.addEventListener('click', function() {
window.location.href = targetUrl;
});
}
if (autoRedirectEnabled && countdown > 0 && countdownElement && targetUrl) {
var countdownTimer = setInterval(function() {
countdown--;
if (countdownElement) {
var displayText = countdownTemplate.replace('{seconds}', countdown);
countdownElement.textContent = displayText;
}
if (progressElement) {
var progress = (initialCountdown - countdown) / initialCountdown;
progressElement.style.width = (100 - (progress * 100)) + '%';
}
if (countdown <= 0) {
clearInterval(countdownTimer);
if (continueButton) {
continueButton.click();
}
}
}, 1000);
}
})();
</script>
</body>
</html>
使用
在主题的/templates/目录下新建立一个redirect.html,将上面代码粘贴进去,如下图所示:
进入主题的/templates/目录下
创建名为redirect.html
将上面的代码复制进去并保存
最后进入网站后台管理,清理模板缓存即可