{"id":15100,"date":"2026-08-19T10:34:58","date_gmt":"2026-08-19T02:34:58","guid":{"rendered":"https:\/\/blog.hoyo.idv.tw\/?p=15100"},"modified":"2026-08-19T10:34:58","modified_gmt":"2026-08-19T02:34:58","slug":"pwa-share_target-%e4%bd%bf%e7%94%a8%e3%80%8c%e5%88%86%e4%ba%ab%e3%80%8d%e7%aa%81%e7%a0%b4-android-%e7%b6%b2%e9%a0%81%e4%b8%8a%e5%82%b3%e7%85%a7%e7%89%87%e8%a2%ab%e7%a7%bb%e9%99%a4-exif-gps-%e5%95%8f","status":"publish","type":"post","link":"https:\/\/blog.hoyo.idv.tw\/?p=15100","title":{"rendered":"PWA share_target - \u4f7f\u7528\u300c\u5206\u4eab\u300d\u7a81\u7834 Android \u7db2\u9801\u4e0a\u50b3\u7167\u7247\u88ab\u79fb\u9664 Exif GPS \u554f\u984c"},"content":{"rendered":"<p>--<\/p>\n<h2>\u7d50\u8ad6<\/h2>\n<p>\u70ba\u4e86\u7a81\u7834 Android \u5f9e<span style=\"color: #ff0000;\"><strong>\u76f8\u7c3f<\/strong><\/span>\u3001<span style=\"color: #ff0000;\"><strong>\u7db2\u9801<\/strong><\/span>\u4e0a\u50b3\u79fb\u9664\u5730\u7406\u8cc7\u8a0a\uff0c\u5fc5\u9808\u5f9e<span style=\"color: #ff0000;\"><strong>\u6a94\u6848<\/strong><\/span>\u4f7f\u7528<span style=\"color: #ff0000;\"><strong>\u5206\u4eab<\/strong><\/span>\u4f86\u4e0a\u50b3\u7167\u7247\u3002<\/p>\n<p>--<\/p>\n<h2>\u5206\u4eab<\/h2>\n<p>\u8981\u4f7f\u7528\u5206\u4eab\uff0c\u9664\u4e86\u5beb App \u4e5f\u53ef\u4ee5\u4f7f\u7528 PWA\uff0c\u4e0d\u904e PWA \u7684\u5206\u4eab\u53ea\u652f\u63f4 Android \u53ef\u80fd iOS \u6c92\u6709\u9019\u500b\u554f\u984c\u5427<\/p>\n<p><a href=\"https:\/\/blog.hoyo.idv.tw\/wp-content\/uploads\/2026\/07\/2026-07-24-14-39-16.png\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" class=\"alignnone size-large wp-image-15119\" src=\"https:\/\/blog.hoyo.idv.tw\/wp-content\/uploads\/2026\/07\/2026-07-24-14-39-16-600x201.png\" alt=\"\" width=\"600\" height=\"201\" srcset=\"https:\/\/blog.hoyo.idv.tw\/wp-content\/uploads\/2026\/07\/2026-07-24-14-39-16-600x201.png 600w, https:\/\/blog.hoyo.idv.tw\/wp-content\/uploads\/2026\/07\/2026-07-24-14-39-16-300x100.png 300w, https:\/\/blog.hoyo.idv.tw\/wp-content\/uploads\/2026\/07\/2026-07-24-14-39-16-768x257.png 768w, https:\/\/blog.hoyo.idv.tw\/wp-content\/uploads\/2026\/07\/2026-07-24-14-39-16.png 923w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>--<\/p>\n<h2>\u5be6\u4f5c<\/h2>\n<ul>\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Progressive_web_apps\/Manifest\/Reference\/share_target\">share_target - Web app manifest | MDN<\/a><\/li>\n<\/ul>\n<p>manifest.json<\/p>\n<pre class=\"lang:default decode:true\">{\r\n  \"share_target\": {\r\n    \"action\": \"\/share-target\",\r\n    \"method\": \"POST\",\r\n    \"enctype\": \"multipart\/form-data\",\r\n    \"params\": {\r\n      \"files\": [\r\n        {\r\n          \"name\": \"shared_files\",\r\n          \"accept\": [\r\n            \"*\/*\"\r\n          ]\r\n        }\r\n      ]\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>sw.js<\/p>\n<pre class=\"lang:default decode:true\">self.addEventListener('fetch', function (e) {\r\n    var u = new URL(e.request.url), t = new URL('\/share-target', self.registration.scope);\r\n    if (e.request.method === 'POST' &amp;&amp; u.pathname === t.pathname) e.respondWith(handleShare(e.request));\r\n});\r\n\r\nasync function handleShare(request) {\r\n    try {\r\n        var form = await request.formData();\r\n        var files = form.getAll('shared_files').filter(function (x) {\r\n            return x instanceof File;\r\n        });\r\n        if (!files.length) throw new Error('\u6c92\u6709\u6536\u5230\u5206\u4eab\u6a94\u6848');\r\n\r\n        await saveFiles(files);\r\n\r\n        return Response.redirect(new URL('\/Home\/SharedFiles', self.registration.scope).href, 303);\r\n    } catch (error) {\r\n        console.error('[SW] \u8655\u7406\u5206\u4eab\u6a94\u6848\u5931\u6557:', error);\r\n    }\r\n}\r\n\r\nfunction openDB() {\r\n    return new Promise(function (resolve, reject) {\r\n        var r = indexedDB.open(DB_NAME, DB_VERSION);\r\n        r.onupgradeneeded = function () {\r\n            if (!r.result.objectStoreNames.contains(STORE_NAME)) r.result.createObjectStore(STORE_NAME, {autoIncrement: true});\r\n        };\r\n        r.onsuccess = function () {\r\n            resolve(r.result);\r\n        };\r\n        r.onerror = function () {\r\n            reject(r.error);\r\n        };\r\n    });\r\n}\r\n\r\nasync function saveFiles(files) {\r\n    var db = await openDB();\r\n    try {\r\n        await new Promise(function (resolve, reject) {\r\n            var tx = db.transaction(STORE_NAME, 'readwrite'), s = tx.objectStore(STORE_NAME);\r\n            files.forEach(function (f) {\r\n                s.add({name: f.name, type: f.type, size: f.size, lastModified: f.lastModified, file: f, timestamp: Date.now()});\r\n            });\r\n            tx.oncomplete = resolve;\r\n            tx.onerror = function () {\r\n                reject(tx.error);\r\n            };\r\n            tx.onabort = function () {\r\n                reject(tx.error || new Error('IndexedDB \u5beb\u5165\u4e2d\u6b62'));\r\n            };\r\n        });\r\n    } finally {\r\n        db.close();\r\n    }\r\n}\r\n<\/pre>\n<p>\/Home\/SharedFiles \u5c31\u662f\u6a94\u6848\u5206\u4eab\u63a5\u6536\u5f8c\u8655\u7406\u7db2\u9801\u53ca\u7a0b\u5f0f\uff0c\u53ef\u4ee5\u4f7f\u7528 AI \u5beb\u5c31\u597d<\/p>\n<p>--<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p class=\"pvc_stats all \" data-element-id=\"15100\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> &nbsp;3&nbsp;total views, &nbsp;3&nbsp;views today<\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>-- \u7d50\u8ad6 \u70ba\u4e86\u7a81\u7834 Andr...<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p class=\"pvc_stats all \" data-element-id=\"15100\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> &nbsp;3&nbsp;total views, &nbsp;3&nbsp;views today<\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[31],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=\/wp\/v2\/posts\/15100"}],"collection":[{"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=15100"}],"version-history":[{"count":9,"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=\/wp\/v2\/posts\/15100\/revisions"}],"predecessor-version":[{"id":15193,"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=\/wp\/v2\/posts\/15100\/revisions\/15193"}],"wp:attachment":[{"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=15100"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=15100"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.hoyo.idv.tw\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=15100"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}