by Rain Chu | 3 月 6, 2024 | Javascript , NodeJS , web
Web Push 是一種標準的 Web 協議,允許網站向使用者發送推播通知。這項功能可用於各種目的,例如:
提醒使用者有新的內容或更新
提供即時通知,例如交易狀態或聊天訊息
提高使用者參與度
準備工作
前端訂閱推播服務的 js 檔案
前端訂閱推播服務的網頁,需要包含訂閱服務的 js
後端紀錄使用者訂閱資訊的服務
後端推播訊息的服務
後端註冊訊息伺服器的程式碼
建立前端網頁的訂閱表單
這個檔案將包含安裝、激活、攔截請求和推播事件的處理器。創建一個名為sw.js
的檔案,並將其放在你網站的根目錄下
// 安裝Service Worker
self.addEventListener('install', function(event) {
console.log('Service Worker 安裝成功');
});
// Service Worker 激活
self.addEventListener('activate', function(event) {
console.log('Service Worker 激活成功');
});
// 監聽推播事件
self.addEventListener('push', function(event) {
var title = '推播通知';
var options = {
body: '這是一條推播消息。',
icon: 'icon.png',
badge: 'badge.png'
};
event.waitUntil(self.registration.showNotification(title, options));
});
在你的網站上註冊一個Service Worker,這是實現Web推播的必要步驟。Service Worker將在背景執行,即使用戶沒有直接訪問你的網站也能接收通知。通常會把下面的 javascript 寫在首頁中,觸發訂閱的條件。
// 在主要的JavaScript檔案中
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
console.log('Service Worker 注册成功:', registration);
}).catch(function(error) {
console.log('Service Worker 注册失败:', error);
});
}
navigator.serviceWorker.ready.then(function(registration) {
if (!registration.pushManager) {
alert('此瀏覽器不支持推播通知');
return false;
}
const applicationServerKey = 'your publice key';
// 訂閱推播
registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(applicationServerKey)
}).then(function(subscription) {
console.log('推播訂閱成功:', subscription);
// 發送訂閱資訊到後端
fetch('https://your_webpush_server/subscribe', {
method: 'post',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
subscription: subscription
}),
});
}).catch(function(error) {
console.log('推播訂閱失败:', error);
});
提供紀錄訂閱訊息的服務
這一段的作法很多,通常用你原本伺服器中的解決方案,例如 php,asp.net,nodejs,python,GO等,我這邊為了方便,用nodejs示範下
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();
app.use(cors());
app.use(bodyParser.json());
const subscriptions = {}; // 在實際應用中,應使用資料庫儲存訂閱資訊
const webPush = require('web-push');
// 設置你的VAPID鑰匙
webPush.setVapidDetails(
'mailto:[email protected] ',
'your publiec key',
'your private key'
};
app.post('/subscribe', (req, res) => {
const subscription = req.body;
const key = subscription.endpoint; // 使用endpoint作為唯一鑰匙
subscriptions[key] = subscription;
console.log('subscripted');
console.log(subscription);
// subscription是從前端發送到後端的訂閱對象
webPush.sendNotification(subscription.subscription, '消息內容')
.then(result => console.log('推播成功'))
.catch(err => console.log('推播失敗', err));
res.status(200).json({message: '訂閱成功'});
});
app.listen(8060, () => console.log('伺服器運行在8060端口'));
其中 sendNotification 平常應該是要放在 webpush service中的,這邊加入是用來測試使用
生成VAPID鑰匙 (自願應用伺服器身份驗證)
大部分現代瀏覽器(如Chrome、Firefox、Edge)都支持Web推播API,但是如果你不用市面上的解決方案如 OneSignal 而是要直接與這些瀏覽器的推播服務交互的話,需要使用VAPID(自願應用伺服器身份驗證)鑰匙進行身份驗證。
生成 VAPID Key 的方法如下
npx web-push generate-vapid-keys
記住保存生成的鑰匙。公鑰將在前端用於訂閱推播,私鑰將在後端用於發送推播。
如果你無法使用npx
(它通常隨npm
自動安裝,作為npm
5.2.0及更高版本的一部分),那麼你可以通過下載最新版本的 nodejs
https://nodejs.org/
或是升級Node.js,或使用版本管理器如nvm
(Node Version Manager)來管理不同版本的Node.js。
參考資料
https://developer.mozilla.org/en-US/docs/Web/API/Push_API
by Rain Chu | 12 月 20, 2023 | wordpress
在WordPress中利用JavaScript隱藏特定欄位是一種有效的方式來改善網站的用戶體驗和介面設計。這需要創建並嵌入自定義的JavaScript腳本到你的WordPress主題中。這個過程涉及幾個關鍵步驟,包括在主題資料夾中創建JavaScript檔案、編寫用於隱藏特定元素的JavaScript代碼、並透過functions.php
檔案將這個腳本加入到WordPress網站中。
1.創建JavaScript檔案 :
在你的主題資料夾(通常位於wp-content/themes/你的主題名稱
)中創建一個新的JavaScript檔案。例如,你可以創建一個名為custom-script.js
的檔案。
2.編寫JavaScript代碼 :
在custom-script.js
檔案中,寫下用於隱藏欄位的JavaScript代碼。例如,如果你想隱藏一個ID為my-field
的元素,代碼可能如下:
document.addEventListener('DOMContentLoaded', function () {
var field = document.getElementById('my-field');
if (field) {
field.style.display = 'none';
}
});
3.將JavaScript檔案加入到WordPress :
在你的主題的functions.php
檔案中,使用wp_enqueue_script
函數將剛剛創建的JavaScript檔案加入到你的網站中。例如:
function add_custom_scripts() {
wp_enqueue_script('custom-script', get_template_directory_uri() . '/custom-script.js', array('jquery'), null, true);
}
add_action('wp_enqueue_scripts', 'add_custom_scripts');
這段代碼會將你的custom-script.js
檔案加入到WordPress,並確保它在網頁加載時被執行。
4.更新並檢查你的網站 :
更新你的WordPress網站並訪問前台,檢查欄位是否已被隱藏。
5.注意 js 的路徑
如果你使用的是子佈景主題,那需要把 get_template_directory_uri() 更改成 get_stylesheet_directory_uri()
function add_custom_scripts() {
wp_enqueue_script('custom-script', get_stylesheet_directory_uri() . '/custom-script.js', array('jquery'), null, true);
}
add_action('wp_enqueue_scripts', 'add_custom_scripts');
這個技術對於希望定制其網站外觀和功能的WordPress用戶來說非常有用,特別是對於那些希望隱藏不必要元素以簡化頁面佈局的用戶。雖然這個過程可能需要一些基本的PHP和JavaScript知識,但它為用戶提供了增強和個性化其網站的機會。
值得注意的是,在進行這些更改時,應該小心操作,並在更改主題檔案之前進行備份。此外,如果你使用子主題,應在子主題中進行所有更改,以避免在主題更新時丟失定制的代碼。這種方法不僅提高了網站的專業程度,還有助於保持良好的用戶體驗。
延伸閱讀:
by Rain Chu | 4 月 13, 2023 | Javascript , 程式
常常有需求要事後調整前台的畫面,尤其現在前端 javascript 的框架一大堆,只能事後處理,把元素的位置變來變去,我這邊舉利用 div 來代表,如何把元素變換位置,讓排版更簡單且容易些。
先準備有原來的 div
<div id="source">
....
</div>
想要把原來的Div移動到目的地的div,id 訂為 dest
<div id="dest">
....
</div>
JQuery 程式碼 appendTo(),把 div 移動到目的地 div 的裡面
$("#source").appendTo("#dest");
除了 appendTo() 最常用,還整理幾個常用的寫法,放在下面
$("#source").insertBefore("#dest");
$("#source").insertAfter("#dest");
$("#source").prependTo("#dest");
$("#source").appendTo("#dest");
參考資料
https://stackoverflow.com/questions/1279957/how-to-move-an-element-into-another-element
by Rain Chu | 3 月 4, 2022 | ASP.NET , C# , 程式
要用 ASP.NET MVC 開發 WEB API給大家使用,前端 javascript 工程師,總是會遇到錯誤訊息 Response to preflight request doesn’t pass access control check: It does not have HTTP ok status,這是一個超常見的 CORS (Cross-Origin Resource Sharing) – 跨來源資源共用錯誤訊息,網路上很多解法,但可以用的情境都不太一樣,我這邊提供一個我覺得最簡單請快速的方法給大家。
解決方法是利用 NuGet 先安裝 Cors 套件
先上 NuGet 搜尋 Microsoft.AspNet.Cors , Microsoft.AspNet.WebApi.Cors,並且安裝起來
將 Cors 註冊起來
在 App_Start/WebApiConfig.cs 的 Register function 加入以下的程式碼
會是長成以下的程式碼
public static void Register(HttpConfiguration config)
{
// Web API 設定和服務
config.EnableCors();
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
設定 WebAPI 的CORS 權限
我們可以在 WebApi 的 Class 上面設定,也可以在 Function 上做標記,但要注意的是不能有多個 CORS 繫結,如果你在 web.config 中設定,這邊就不能再做設定,如果你在 class 等級上設定了, function 等級就不能再設定,也是因為這個原因,所以我喜歡在 function 等級設定或是 class 等級上設定,web.config 比較少去做設定,雖然他有不用修改程式碼的好處。
其中設定值的資料參考請看https://docs.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference
origins,可以設定 (*) ,也可以指定特定網域,看你要對誰開放 headers,通常用 (*) 就可以了 methods,通常用 (*) 就可以了
[System.Web.Http.Cors.EnableCors(origins: "https://yourdomain.com", headers: "*", methods: "*")]
public class ValueController : ApiController
{
}
CORS web.config 的設定方法
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<cors enabled="true" failUnlistedOrigins="true">
<add origin="*" />
<add origin="https://*.yourdomain.com"
allowCredentials="true"
maxAge="120">
<allowHeaders allowAllRequestedHeaders="true">
<add header="header1" />
<add header="header2" />
</allowHeaders>
<allowMethods>
<add method="DELETE" />
</allowMethods>
<exposeHeaders>
<add header="header1" />
<add header="header2" />
</exposeHeaders>
</add>
<add origin="http://*" allowed="false" />
</cors>
</system.webServer>
</configuration>
by Rain Chu | 2 月 28, 2022 | Javascript , 程式
// 發送email
function sendEmail(title,text){
var email = document.createElement("a");
email.id = "sendemail";
email.href = "mailto:[email protected] ?subject="+title+"&body="+ text;
email.click();
}
當使用者在網頁中,再連絡表單中填入資訊後,我們通常會寫入後端資料庫,並且發送通知,以方便管理者使用,但沒有資料庫的人,就需要仰賴使用者自己的電子郵件了,為了統一格式方便,我們還是提供聯絡表單,先幫忙使用者把資料正規化一下,然後在協助它們送出資訊給後端的管理者
近期留言