[Next.js][App router]在LINE內瀏覽器內多選檔案/圖檔觸發onchange事件的問題
因為遭遇了在Android手機LINE瀏覽器內使用網頁時,當設定input type="file"容許多選,在onchange事件取不到多選的檔案。
*我實測若點了界面上的...按鈕,選其他資料夾內的檔案,則不會取不到多選檔案,初步判定是LINE瀏覽器與Android系統之間的溝通問題*
因為暫時還沒有好的方式,所以就在網頁上顯示提示,然後請不能接受的使用者移動到外部瀏覽器來觀看。
下圖是LINE瀏覽器的user agent字串於三星s22手機上
如何確認是LINE瀏覽器就是依靠http header內的user-agent了,以下分為4個步驟,完成用於Next.js app router在網頁上顯示提示的功能。
1. 取得userAgent字串
useEffect(() => {
setUserAgent(typeof window !== 'undefined' && window.navigator.userAgent || '');
}, []);
2. 解析字串,確認包含'Line'字眼
useEffect(() => {
setLineAppBrowser(userAgent.indexOf('Line') !== -1);
}, [userAgent]);
3. 顯示文字提示,並設定跳轉用連結URL
const extUrl = useMemo(() => {
const params = new URLSearchParams(searchParams);
params.set('openExternalBrowser', '1');
return pathname + `?` + params.toString();
}, [pathname, searchParams])
4. LINE使用者依然可以使用單檔案上傳,其他則可以用多選檔案上傳
<input
type="file" name="images" accept="image/*"
multiple={!isLineAppBrowser}
/>
完整程式碼如下
import { useState, useEffect, useMemo } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
export default function App() {
const pathname = usePathname();
const searchParams = useSearchParams();
const [userAgent, setUserAgent] = useState<string>('');
const [isLineAppBrowser, setLineAppBrowser] = useState<boolean>(false);
useEffect(() => {
setUserAgent(typeof window !== 'undefined' && window.navigator.userAgent || '');
}, []);
useEffect(() => {
setLineAppBrowser(userAgent.indexOf('Line') !== -1);
}, [userAgent]);
const extUrl = useMemo(() => {
const params = new URLSearchParams(searchParams);
params.set('openExternalBrowser', '1');
return pathname + `?` + params.toString();
}, [pathname, searchParams])
return (
<form>
{
isLineAppBrowser ? (
<p>
您目前在LINE內建的瀏覽器中,不支援多選上傳。若想要多選上傳,請
<a href={extUrl} > 按這裡</a > 開啟外部瀏覽器!
</p>
) : null
}
<input
type="file" name="images" accept="image/*"
multiple={!isLineAppBrowser}
/>
<input type='submit' value='上傳' />
</form>
);
}
留言