[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>
);
}


留言