lowered.includes(p))
}
function percentIsWellFormed(s) {
// 若包含 %,必須緊接兩位 16 進位;避免 decodeURIComponent 拋錯或繞過
return !/%(?![0-9a-fA-F]{2})/.test(s)
}
function escapeHTML(s) {
// 若你要輸出到頁面,用這個或用 textContent
return s
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
}
// ---- 取得並初步檢查 token ----
function getTokenFromURL() {
const params = new URLSearchParams(window.location.search)
const token = params.get('token')
if (!token) return null
// 先快速字元檢查(未轉 base64url 前)
if (!/^[A-Za-z0-9+/_=-]*$/.test(token)) return null
try {
const normalized = normalizeBase64(token)
if (!isSafeBase64(normalized)) return null
return normalized
} catch {
return null
}
}
// ---- decode + 解析,同時防 XSS ----
function decodeAndParseToken(safeBase64Token) {
if (!safeBase64Token) return {}
let decodedString = ''
try {
decodedString = atob(safeBase64Token) // 可能拋錯
} catch (e) {
console.warn('atob 失敗:', e)
return {}
}
// atob 後再做安全檢查
if (hasControlChars(decodedString)) return {}
if (looksLikeHTMLOrJS(decodedString)) return {}
// 解析 querystring 格式:a=b&c=d
const params = {}
const parts = decodedString.split('&')
if (parts.length > 100) return {} // 避免過多鍵值
for (const part of parts) {
if (!part) continue
const idx = part.indexOf('=')
const rawKey = idx >= 0 ? part.slice(0, idx) : part
const rawVal = idx >= 0 ? part.slice(idx + 1) : ''
// 長度限制,避免 DoS
if (rawKey.length > 256 || rawVal.length > 2048) return {}
// 百分號格式先檢查,避免 decodeURIComponent 拋錯或繞過
if (!percentIsWellFormed(rawKey) || !percentIsWellFormed(rawVal)) return {}
let key = ''
let value = ''
try {
key = decodeURIComponent(rawKey)
value = decodeURIComponent(rawVal)
} catch (e) {
console.warn('decodeURIComponent 失敗:', e)
return {}
}
// 對解碼後的 key/value 再做一輪安全檢查
if (hasControlChars(key) || hasControlChars(value)) return {}
if (looksLikeHTMLOrJS(key) || looksLikeHTMLOrJS(value)) return {}
// 可選:白名單鍵名(若你已知可接受的鍵)
// const allowedKeys = new Set(["uid","exp","sig"]);
// if (!allowedKeys.has(key)) return {};
params[key] = value
}
return params
}
var token = getTokenFromURL()
console.log(token)
// console.log(token) // 安全地輸出 token 值
if (token) {
const decodedParams = decodeAndParseToken(token)
console.log(decodedParams)
// 更新 .count_box 的類
var grace_y = decodedParams.grace_period === '0' ? 0 : 2
var totalYears_grace =
decodedParams.grace_period === '0'
? parseFloat(decodedParams.Period)
: parseFloat(decodedParams.Period) + 2
var totalYears_grace_topage =
decodedParams.grace_period === '0'
? parseFloat(decodedParams.Period)
: '2 +' + parseFloat(decodedParams.Period)
var P = parseFloat(decodedParams.Amount) * 10000 //本金
var r_annual = parseFloat(decodedParams.InterestRate) / 100 //年利率
var r = r_annual / 12 //月利率
var n_totalYears = totalYears_grace //還款期限
var n = (n_totalYears - parseFloat(grace_y)) * 12 //寬限期
// console.log(P, r_annual, r, n_totalYears, n)
var interestDuringGracePeriod = (P * r_annual) / 12
var repayment = (P * (r * Math.pow(1 + r, n))) / (Math.pow(1 + r, n) - 1)
function updateTextContent(selector, value) {
const element = document.querySelector(selector)
if (element) {
element.textContent = value
}
}
function updateInnerHTML(selector, htmlContent) {
const element = document.querySelector(selector)
if (element) {
element.innerHTML = htmlContent
}
}
function formatNumber(num) {
var number = Number(num)
if (isNaN(number)) {
return 'Invalid number'
}
return number.toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
const formattedInterest = formatNumber(interestDuringGracePeriod)
const formattedRepayment = formatNumber(repayment)
// 清空 .loan_information_box 的內容並添加新內容
var loanInfoBoxes = document.querySelectorAll('.loan_information_box')
let g_text_01 = '無'
function updateLoanInfo(content) {
loanInfoBoxes.forEach(box => {
box.innerHTML += content
})
}
// var LoanInformationPresentation = document.getElementById('form-field-c_data')
var totalnum
if (decodedParams.type == '二胎房貸') {
let g_text_01 = decodedParams.grace_period === '1' ? '有' : '無'
document
.querySelector('.count_box')
.classList.toggle('op', decodedParams.grace_period === '0')
if (decodedParams.grace_period === '0') {
updateTextContent('.nograce_period .s_count_t span', formattedRepayment)
} else {
updateTextContent(
'.grace_period .Monthly_payment_during_grace_period .num span',
formattedInterest
)
updateTextContent(
'.grace_period .Monthly_payment_after_grace_period .num span',
formattedRepayment
)
}
if (decodedParams.Amount) {
updateLoanInfo(`
${decodedParams.Amount}萬
貸款額度
`)
}
if (decodedParams.InterestRate) {
updateLoanInfo(`
${decodedParams.InterestRate}%
貸款利率
`)
}
if (decodedParams.grace_period) {
updateLoanInfo(`
`)
}
if (decodedParams.Period) {
updateLoanInfo(`
${totalYears_grace_topage}年
貸款年期
`)
totalnum = {
試算種類: decodedParams.type,
寬限期間月付金: formattedInterest,
寬限期後月付金: formattedRepayment,
貸款額度: decodedParams.Amount,
貸款利率: decodedParams.InterestRate,
寬限期: g_text_01,
貸款年期: totalYears_grace_topage
}
console.log(totalnum)
// LoanInformationPresentation.value = JSON.stringify(totalnum)
// document.cookie = 'c_data=' + JSON.stringify(totalnum)
}
} else if (decodedParams.type == '機車貸款') {
document.querySelector('.count_box').classList.add('op')
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_box li.op a.pc',
'一般試算'
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_box li.op a.m',
'一般試算'
)
updateTextContent('.nograce_period .s_count_t span', formattedRepayment)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p h2.pc',
'機車貸款試算'
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p h2.m',
'機車貸款試算結果'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p p',
'就讓你的機車神隊友,貸你去向更好的明天!
線上輕鬆辦、48小時撥款,享受資金同時仍保有自由'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .tab_container >.flex .w-full .but_box',
`
`
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .nograce_period .text_box .s_title',
'機車貸款試算'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .nograce_period .img_box',
'

'
)
updateInnerHTML(
'.Goodwill_Loans_Free_Home_Valuation_box .Publicity_box',
`
現省評估手續費15000元!
好事貸資金應援團參上!
加入好事貸
讓專業的資金應援團為你消除選擇障礙,
量身推薦最適合你的貸款方案,資金不卡卡!
`
)
if (decodedParams.Amount) {
updateLoanInfo(`
${decodedParams.Amount}萬
貸款額度
`)
}
if (decodedParams.Period) {
updateLoanInfo(`
${decodedParams.Period}年
貸款年期
`)
}
totalnum = {
試算種類: decodedParams.type,
月付金: formattedRepayment,
貸款額度: decodedParams.Amount,
貸款利率: decodedParams.InterestRate,
貸款年期: decodedParams.Period
}
console.log(totalnum)
// LoanInformationPresentation.value = JSON.stringify(totalnum)
// document.cookie = 'c_data=' + JSON.stringify(totalnum)
} else if (decodedParams.type == '汽車貸款') {
document.querySelector('.count_box').classList.add('op')
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_box li.op a.pc',
'一般試算'
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_box li.op a.m',
'一般試算'
)
updateTextContent('.nograce_period .s_count_t span', formattedRepayment)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p h2.pc',
'汽車貸款試算'
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p h2.m',
'汽車貸款試算結果'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p p',
`想要圓夢資金?投資理財?財務整理?
就靠愛車資金神助攻,讓夢想型態再進化!`
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .tab_container >.flex .w-full .but_box',
`
`
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .nograce_period .text_box .s_title',
'汽車貸款'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .nograce_period .img_box',
'

'
)
updateInnerHTML(
'.Goodwill_Loans_Free_Home_Valuation_box .Publicity_box',
`
現省評估手續費15000元!
好事貸資金應援團參上!
加入好事貸
讓專業的資金應援團為你消除選擇障礙,
量身推薦最適合你的貸款方案,資金不卡卡!
`
)
if (decodedParams.Amount) {
updateLoanInfo(`
${decodedParams.Amount}萬
貸款額度
`)
}
if (decodedParams.InterestRate) {
updateLoanInfo(`
${decodedParams.InterestRate}%
貸款利率
`)
}
if (decodedParams.Period) {
updateLoanInfo(`
${decodedParams.Period}年
貸款年期
`)
}
totalnum = {
試算種類: decodedParams.type,
月付金: formattedRepayment,
貸款額度: decodedParams.Amount,
貸款利率: decodedParams.InterestRate,
貸款年期: decodedParams.Period
}
console.log(totalnum)
// LoanInformationPresentation.value = JSON.stringify(totalnum)
// document.cookie = 'c_data=' + JSON.stringify(totalnum)
} else if (decodedParams.type == '其他貸款') {
document.querySelector('.count_box').classList.add('op')
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_box li.op a.pc',
'一般試算'
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_box li.op a.m',
'一般試算'
)
updateTextContent('.nograce_period .s_count_t span', formattedRepayment)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p h2.pc',
'其他貸款試算'
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p h2.m',
'其他貸款試算'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p p',
`每個月要繳多少錢?合理分配貸款支出,
反而能讓財務規劃更彈性!`
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .tab_container >.flex .w-full .but_box',
`
`
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .nograce_period .text_box .s_title',
'你的貸款'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .nograce_period .img_box',
'

'
)
updateInnerHTML(
'.Goodwill_Loans_Free_Home_Valuation_box .Publicity_box',
`
現省評估手續費15000元!
好事貸資金應援團參上!
加入好事貸
讓專業的資金應援團為你消除選擇障礙,
量身推薦最適合你的貸款方案,資金不卡卡!
`
)
if (decodedParams.Amount) {
updateLoanInfo(`
${decodedParams.Amount}萬
貸款額度
`)
}
if (decodedParams.InterestRate) {
updateLoanInfo(`
${decodedParams.InterestRate}%
貸款利率
`)
}
if (decodedParams.Period) {
updateLoanInfo(`
${decodedParams.Period}年
貸款年期
`)
}
totalnum = {
試算種類: decodedParams.type,
月付金: formattedRepayment,
貸款額度: decodedParams.Amount,
貸款利率: decodedParams.InterestRate,
貸款年期: decodedParams.Period
}
console.log(totalnum)
// LoanInformationPresentation.value = JSON.stringify(totalnum)
// document.cookie = 'c_data=' + JSON.stringify(totalnum)
} else if (decodedParams.type == '月付金負擔試算') {
document.querySelector('.count_box').classList.add('op2')
document
.querySelector('.Main_tabbed_blocks_box_bg.result .tab_container')
.classList.add('op2')
var tAmount = decodedParams.Amount
var tb1 = parseFloat(decodedParams.b1) || 0
var tb2 = parseFloat(decodedParams.b2) || 0
var tb3 = parseFloat(decodedParams.b3) || 0
var tb4 = parseFloat(decodedParams.b4) || 0
var tb5 = parseFloat(decodedParams.b5) || 0
var Total_monthly_payment = tb1 + tb2 + tb3 + tb4 + tb5
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_box li.op a.pc',
'月付金負擔試算'
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_box li.op a.m',
'月付金負擔試算'
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p h2.pc',
'月付金負擔試算'
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p h2.m',
'月付金負擔試算'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .tab_container >.flex .w-full .but_box',
`
`
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .tab_main_box .t_p p',
`建議一定要培養良好的財務檢查習慣,
定期試算月負擔比例,隨時調整你的支出狀態!`
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .burden .Total_monthly_payment .num_text span',
formatNumber(Total_monthly_payment)
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .burden .average_monthly_income .num_text span',
formatNumber(tAmount)
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .burden .Recommended_upper_limit_burden .num_text span',
formatNumber(tAmount * 0.6)
)
updateInnerHTML(
'.Goodwill_Loans_Free_Home_Valuation_box .Publicity_box',
`
現省評估手續費15000元!
好事貸資金應援團參上!
加入好事貸
讓專業的資金應援團為你消除選擇障礙,
量身推薦最適合你的貸款方案,資金不卡卡!
`
)
var total_percentage = (Total_monthly_payment / tAmount) * 100
// console.log(total_percentage)
var prompt_text = document.querySelector(
'.Main_tabbed_blocks_box_bg.result .burden .prompt_text'
)
if (total_percentage && total_percentage < 60) {
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .burden .burden_main .img_box',
`
月負擔比例
健康
${total_percentage.toFixed(0)}%
`
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .burden .prompt_text',
'健康'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .burden .burden_by',
`你的月負擔比例低於60%,處於健康狀態!
建議立即進行財務整理,
才不會讓信用出現大問題!`
)
prompt_text.style.backgroundColor = '#00B079'
} else if (total_percentage >= 60 && total_percentage < 80) {
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .burden .burden_main .img_box',
`
月負擔比例
風險
${total_percentage.toFixed(0)}%
`
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .burden .prompt_text',
'風險'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .burden .burden_by',
`你的月負擔比例超過60%,處於風險狀態!
建議立即進行財務整理,
才不會讓信用出現大問題!`
)
prompt_text.style.backgroundColor = '#D1A741'
} else if (total_percentage >= 80 && total_percentage < 100) {
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .burden .burden_main .img_box',
`
月負擔比例
注意
${total_percentage.toFixed(0)}%
`
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .burden .prompt_text',
'注意'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .burden .burden_by',
`你的月負擔比例超過80%,處於注意狀態!
建議立即進行財務整理,
才不會讓信用出現大問題!`
)
prompt_text.style.backgroundColor = '#FF4106'
} else if (total_percentage >= 100) {
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .burden .burden_main .img_box',
`
月負擔比例
危險
${total_percentage.toFixed(0)}%
`
)
updateTextContent(
'.Main_tabbed_blocks_box_bg.result .burden .prompt_text',
'危險'
)
updateInnerHTML(
'.Main_tabbed_blocks_box_bg.result .burden .burden_by',
`你的月負擔比例超過100%,處於危險狀態!
建議立即進行財務整理,
才不會讓信用出現大問題!`
)
prompt_text.style.backgroundColor = '#D41E1E'
}
totalnum = {
試算種類: decodedParams.type,
平均月收入: formatNumber(Total_monthly_payment),
月付金總額: formatNumber(tAmount),
建議負擔上限: formatNumber(tAmount * 0.6),
月負擔比例: total_percentage.toFixed(0) + '%'
}
console.log(totalnum)
// LoanInformationPresentation.value = JSON.stringify(totalnum)
// document.cookie = 'c_data=' + JSON.stringify(totalnum)
}
// console.log(interestDuringGracePeriod.toFixed(0))
// console.log(repayment.toFixed(0))
// var bns_poen = document.querySelector('.share_form_box .button_box')
// function bns_poenClick() {
// var shareFormBox = document.querySelector('.share_form_box')
// var shareFnBox = document.querySelector('.share_fn_box')
// var shareButBox = document.querySelector('.share_box .but_box a')
// shareFormBox.classList.toggle('op')
// shareFnBox.classList.toggle('op')
// shareButBox.classList.toggle('op')
// }
// bns_poen.addEventListener('click', bns_poenClick)
// document
// .querySelector('.button_box .share_r_box .open')
// .addEventListener('click', function () {
// if (!document.querySelector('.share_form_box').classList.contains('op')) {
// captureScreen()
// }
// })
// function captureScreen() {
// setTimeout(function () {
// html2canvas(
// document.querySelector('.Trial_calculation_box .flex .count_box')
// ).then(canvas => {
// const image = canvas
// .toDataURL('image/png')
// .replace('image/png', 'image/octet-stream')
// const link = document.createElement('a')
// link.download = 'screenshot.png'
// link.href = image
// document.body.appendChild(link)
// link.click()
// document.body.removeChild(link)
// })
// }, 800)
// }
//分享
// var copyLink = document.querySelector('.copy a')
// copyLink.addEventListener('click', function (event) {
// event.preventDefault()
// var textArea = document.createElement('textarea')
// textArea.value = window.location.href
// document.body.appendChild(textArea)
// textArea.select()
// document.execCommand('copy')
// document.body.removeChild(textArea)
// // 顯示複製成功的提示
// alert('網址已複製: ' + textArea.value)
// })
var currentUrl = window.location.href
updateInnerHTML(
'.share_fn_box .facebook',
`
`
)
updateInnerHTML(
'.share_fn_box .line',
`
`
)
//再算一次
var backButton = document.querySelector('.Count_again_box a')
function getReferrer() {
return document.referrer
}
var referrer = getReferrer()
var parsedUrl
try {
parsedUrl = new URL(referrer)
// 將條件判斷移到 try 區塊
if (
parsedUrl.hostname === 'houseloan.tw' &&
parsedUrl.pathname.startsWith('/loan-calculator/')
) {
// 相應的操作
}
} catch (e) {
console.log('無效的URL')
// 當解析 URL 失敗時的操作
var shareFormBox = document.querySelector('.share_form_box')
var shareFnBox = document.querySelector('.share_fn_box')
var shareButBox = document.querySelector('.share_box .but_box a')
shareFormBox.classList.toggle('op')
shareFnBox.classList.toggle('op')
shareButBox.classList.toggle('op')
document
.querySelector('.share_form_box .button_box')
.addEventListener('click', function (event) {
shareFormBox.classList.toggle('op')
shareFnBox.classList.toggle('op')
shareButBox.classList.toggle('op')
event.preventDefault()
checkReferrerAndAct()
})
}
function checkReferrerAndAct() {
if (!referrer) {
console.log('無referrer或無法獲取')
location.href = 'https://houseloan.tw/loan-calculator/'
return
}
try {
parsedUrl = new URL(referrer)
} catch (e) {
console.log('無效的URL')
location.href = 'https://houseloan.tw/loan-calculator/'
return
}
// 檢查基本網址是否符合指定的格式
if (
parsedUrl.hostname === 'houseloan.tw' &&
parsedUrl.pathname.startsWith('/loan-calculator/')
) {
console.log('使用者來自指定的網址')
window.history.back()
} else {
location.href = 'https://houseloan.tw/loan-calculator/'
}
}
function isSafari() {
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
}
backButton.addEventListener('click', function (event) {
event.preventDefault()
if (
navigator.userAgent.match(/(iPod|iPhone|iPad)/) &&
navigator.userAgent.match(/AppleWebKit/) &&
isSafari()
) {
location.href = 'https://houseloan.tw/loan-calculator/'
} else {
checkReferrerAndAct()
}
})
//關閉彈跳視窗
document
.querySelector('.Bonding_Success_box_bg .closure_box')
.addEventListener('click', function (e) {
// var Bonding_Success_box_bgBoxBg = document.querySelector(
// '.Bonding_Success_box_bg'
// )
// Bonding_Success_box_bgBoxBg.classList.remove('op')
e.preventDefault()
if (
navigator.userAgent.match(/(iPod|iPhone|iPad)/) &&
navigator.userAgent.match(/AppleWebKit/) &&
isSafari()
) {
location.href = 'https://houseloan.tw/loan-calculator/'
} else {
checkReferrerAndAct()
}
})
} else {
location.href = 'https://houseloan.tw/loan-calculator/'
}