解决android native包webview,webview中的请求blocked by CORS policy

在stack overflow查,差不多查到的都是些webView.getSettings().setxxx,没用。在github上找别的类似的android native包webview运行pwa的项目,把它们的webView.getSettings().setxxx全搬过来,写了有一页多,一个有用的都没有,他们开发没有遇到过同源限制嘛!!!

还有一种,配置安卓项目本身的network,就是写一个network_security_config.xml,把服务器地址放到subdomain里。这个听了不大靠谱,因为同源策略是浏览器的限制,换言之,是webview的限制,应该要配置webview相关的,而不是app相关

查到的另外一种较多的方法是override shouldInterceptRequest,意思就是拦截request,然后进行一些这样那样的操作,帮助服务端返回数据,这个是最靠谱的。把他们的代码统统搬过来一个一个试了,都用不了,看来得自己写了

其实关于shouldInterceptRequest,官方文档是有example的,不过看起来虽然写了什么with same-origin policy,它主要的意思是同“协议”的源。同源策略不是说协议,域名,端口一致嘛,这些本地文件本来是file://,协议不一样,获取不到的,它通过assetLoader转一下,把file://xxx.js转成https://appassets.androidplatform.net/xxx.js,这样协议就都是https了,就能获取到并加载到webview中了:
https://developer.android.com/develop/ui/views/layout/webapps/load-local-content#assetloader

让server那边加Access-Control-Allow-Origin响应头,不现实,我们只是做poc,让人家好好的服务端改数据,怎么可能,人家能理咱?

之前我用react native开发过一版,也是跑在android tv上的,用的同一套restapi,为啥当时非常没遇到这些问题啊

搜了一下官方文档,好家伙,XMLHttpRequest是不存在CORS问题的:
https://reactnative.dev/docs/network#using-other-networking-libraries

好嘛,那要是这样说的话,直接拦截url,然后用XMLHttpRequest去请求,然后把响应返回回去,不就好了(智将

结果在那边满头大汗弄了半天,好不容易XMLHttpRequest转过去了,但怎么也没把XMLHttpResponse转成shouldInterceptRequest需要返回的WebResourceResponse,本来就不会kotlin,全组就我一个人弄这个,硬着头皮嗯写,写的烦死了

突然灵机一动,既然转的太麻烦,干脆不转了,同源策略限制是吧,我自己安一个响应头上去!

    private class LocalContentWebViewClient(private val assetLoader: WebViewAssetLoader) :
        WebViewClientCompat() {
        val INTERCEPT_KEY_LOCAL_ASSET = "https://appassets.androidplatform.net/"

        val client = OkHttpClient()

        var headers: MutableMap<String, String> = java.util.HashMap()

        init {
            headers["Access-Control-Allow-Origin"] = "*"
            headers["Access-Control-Allow-Headers"] =
                "隐去,按照您的实际请求的headers来写"
        }

        fun requestDataFromServer(request: WebResourceRequest): ResponseBody? {
            val url = request.url.toString()
            var responseBody: ResponseBody? = null;
            try {
                val req = Request.Builder()
                    .url(url)
                    .headers(request.requestHeaders.toHeaders())
                    .build()
                val call = client.newCall(req)
                val resp = call.execute()
                responseBody = resp.body
            } catch (e: Exception) {
                println("url failed" + url + e.toString());
            }
            return responseBody
        }

        override fun shouldInterceptRequest(
            view: WebView,
            request: WebResourceRequest
        ): WebResourceResponse? {
            val url = request.url.toString()
            return if (url.contains(INTERCEPT_KEY_LOCAL_ASSET)) {
                assetLoader.shouldInterceptRequest(request.url)
            } else if (url.contains(".jpeg")) {
                val responseBody = requestDataFromServer(request)
                val data: InputStream? = responseBody?.byteStream()
                return WebResourceResponse(
                    "image/jpeg",
                    "UTF-8",
                    200,
                    "OK",
                    headers,
                    data
                )
            } else if (url.contains(".png")) {
                val responseBody = requestDataFromServer(request)
                val data: InputStream? = responseBody?.byteStream()
                return WebResourceResponse(
                    "image/png",
                    "UTF-8",
                    200,
                    "OK",
                    headers,
                    data
                )
            } else {
                val responseBody = requestDataFromServer(request)
                val data: InputStream? = responseBody?.byteStream()
                return WebResourceResponse(
                    "application/json",
                    "UTF-8",
                    200,
                    "OK",
                    headers,
                    data
                )
            }
        }
    }

代码就贴在这里了,供各位同样受困于这个问题的朋友们参考,第一个url.contains(INTERCEPT_KEY_LOCAL_ASSET),就是本地的html css js文件,按照android developer官方写法就好;其他的三种是一个意思,在外面用okhttp库获取response,安上跨域的header,把response body塞到里面stream里面返回,唯一的不同就是MIME type的不同,图片格式不能用"application/json",要分开

当然如果优化的还有很大的优化空间,比方说okhttp请求用异步的写法更好,还有直接把status code设置为200,肯定是不对的,我只是一个做poc的,懒得改了,验证完可行性给领导展示了就完了,相信server端同事们的水平(x) 大家如果参考记得改改嗷

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/776874.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无人机运营合格证及无人机驾驶员合格证(AOPA)技术详解

无人机运营合格证及无人机驾驶员合格证&#xff08;AOPA&#xff09;技术详解如下&#xff1a; 一、无人机运营合格证 无人机运营合格证是无人机运营企业或个人必须获得的证书&#xff0c;以确保无人机在运营过程中符合相关法规和标准。对于无人机运营合格证的具体要求和申请…

【计算机毕业设计】020基于weixin小程序订餐系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【Linux进阶】文件系统4——文件系统特性

1.磁盘组成与分区的复习 首先说明一下磁盘的物理组成&#xff0c;整块磁盘的组成主要有&#xff1a; 圆形的碟片&#xff08;主要记录数据的部分&#xff09;&#xff1b;机械手臂&#xff0c;与在机械手臂上的磁头&#xff08;可擦写碟片上的数据);主轴马达&#xff0c;可以…

Beats:使用 Filebeat 从 Python 应用程序中提取日志

本指南演示了如何从 Python 应用程序中提取日志并将其安全地传送到 Elasticsearch Service 部署中。你将设置 Filebeat 来监控具有标准 Elastic Common Schema (ECS) 格式字段的 JSON 结构日志文件&#xff0c;然后你将在 Kibana 中查看日志事件发生的实时可视化。虽然此示例使…

python基础语法 006 内置函数

1 内置函数 材料参考&#xff1a;内置函数 — Python 3.12.4 文档 Python 解释器内置了很多函数和类型&#xff0c;任何时候都能直接使用 内置函数有无返回值&#xff0c;是python自己定义&#xff0c;不能以偏概全说都有返回值 以下为较为常用的内置函数&#xff0c;欢迎补充…

【二】Ubuntu24虚拟机在Mac OS的VMware Fusion下无法联网问题

文章目录 1.环境背景2. 需求背景3. 解决方法3.1 在mac的终端查看虚拟机NAT网络3.2 查看unbuntu节点2的网络配置3.3 问题定位与解决3.3.1 检查是否有冲突3.3.2 冲突解决方法 4. 总结4.1 NAT 网关的原理4.2 VMware Fusion 的 NAT 模式4.3 为什么网关冲突会引起问题4.4 理解配置冲…

transformer初探

transformer初探 self-attentionmultihead-attentionencoderdecoder self-attention 其实就是三个矩阵&#xff0c; W q W_q Wq​、 W k W_k Wk​、 W v W_v Wv​&#xff0c;这三个矩阵就是需要训练的参数。分别得到每个token对应的 q q q k k k v v v&#xff0c;其中 q …

系统测试-测试方法学习

目录 &#xff08;1&#xff09;等价类 &#xff08;2&#xff09;边界值 &#xff08;3&#xff09;正交&#xff1a;&#xff08;只用于确定排列组合&#xff0c;不确定具体内容&#xff09; (4)判定表法 &#xff08;5&#xff09;流程分析法 &#xff08;6&#xff0…

【vue组件库搭建04】使用vitepress搭建站点并部署到github

前言 基于vitePress搭建文档站点&#xff0c;使用github pages进行部署 安装VitePress 1.Node.js 18 及以上版本 2.npm add -D vitepress 3.npx vitepress init 4.将需要回答几个简单的问题&#xff1a; ┌ Welcome to VitePress! │ ◇ Where should VitePress initi…

Vue2基础 14:自定义指令

自定义指令 1 函数式1.1 案例--v-text放大10倍 2 对象式2.1 案例--v-fbind默认获取焦点&#xff08;函数式&#xff09;2.2 案例--v-fbind默认获取焦点&#xff08;对象式&#xff09; 3 自定义指令容易犯的错4 全局指令写法&#xff08;参考过滤器写法&#xff09;&#xff1a…

C51单片机程序及仿真(加减器)

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

AndroidKille更新apktool插件-cnblog

AndroidKiller不更新插件容易报错 apktool插件更新 网址 Releases iBotPeaches/Apktool (github.com) 找到apktool管理器 填入apktool位置&#xff0c;并输入apktool名字 选择默认的apktool版本 x掉&#xff0c;退出重启 可以看到反编译完成了 dex2jar 更新 网址 Release…

数据库-多表设计 多表查询

多表设计 一对多 一对多关系实现&#xff1a;在数据库表中多的一方&#xff0c;添加字段&#xff0c;来关联一的一方的主键 外键约束 -- 创建表时指定 create table 表名(字段名 数据类型,...[constraint] [外键名称] foreign key (外键字段名) references 主表…

帕金森患者饮食小贴士 满满的爱与关怀哦!

&#x1f34e; 首先&#xff0c;要多吃水果和蔬菜&#xff01;新鲜蔬果富含维生素和矿物质&#xff0c;对神经系统有很好的保护作用。&#x1f966; 特别是绿叶蔬菜&#xff0c;比如菠菜、生菜&#xff0c;它们都是健康的小天使&#xff01;&#x1f49a; &#x1f372; 其次&a…

vue2-vue3响应式原理

我们先来看一下响应式意味着什么&#xff1f;我们来看一段代码&#xff1a; m有一个初始化的值&#xff0c;有一段代码使用了这个值&#xff1b;那么在m有一个新的值时&#xff0c;这段代码可以自动重新执行&#xff1b; let m 20 console.log(m) console.log(m * 2)m 40上…

政策护航新能源助推绿色经济腾飞

随着全球气候变化问题日益严重&#xff0c;新能源行业的发展成为推动绿色经济腾飞的重要引擎。近年来&#xff0c;各国政府纷纷出台政策支持新能源产业&#xff0c;旨在激发行业活力&#xff0c;促进经济可持续发展。本文将从政策红利的角度&#xff0c;探讨新能源行业发展的现…

lnmp php7 安装ssh2扩展

安装ssh2扩展前必须安装libssh2包 下载地址: wget http://www.libssh2.org/download/libssh2-1.11.0.tar.gzwget http://pecl.php.net/get/ssh2-1.4.tgz &#xff08;这里要换成最新的版本&#xff09; 先安装 libssh2 再安装 SSH2: tar -zxvf libssh2-1.11.0.tar.gzcd libss…

【Linux进阶】ext2文件系统(inode)

1.再谈inode (1) 理解inode&#xff0c;要从文件储存说起。 文件储存在硬盘上&#xff0c;硬盘的最小存储单位叫做"扇区"&#xff08;Sector&#xff09;。每个扇区储存512字节&#xff08;相当于0.5KB&#xff09;。操作系统读取硬盘的时候&#xff0c;不会一个个…

方法引用 异常 file

一.方法引用 1.方法引用概述 eg: 表示引用run1类里面的sxxxx方法 把这个方法当做抽象方法的方法体 &#xff1a;&#xff1a;是方法引用符 //方法引用Integer[] arr{4,3,1,6,2,7,8,5};Arrays.sort(arr,run1::subtraction);System.out.println(Arrays.toString(arr));}publi…