Blog

Blog

PHODAL

混合应用:从 file 协议到本地 HTTP 服务器

过去的几个月里,我们一直在开发一个混合应用。前端框架使用的是 Angular,但是在某些 Android 机型上运行的时候,报了以下的错误:

main.aca1d67….bundle.js:1235 EXCEPTION: Uncaught (in promise): SecurityError: Failed to execute 
'replaceState' on 'History': A history state object with URL 'file:///#/' cannot be created in a document with 
origin 'file://' and URL 'file:///android_asset/www/index.html'.t.handleError @

错误的主要原因是:History API 在某些 Chrome 内核的 WebView 上不支持 file:// 协议。据不完成测试统计,版本在 45~49 之间,都有这个问题。

随后找到了官方文档中的 issue:Cannot run angular 2+ from file:/// - looks like 'base href="/"' is the issue

官方 issue 中的一个高赞答案,一共两步,并是不 work。

1.将 Router 配置为 Hash

CommonModule,RouterModule.forRoot(routes,{useHash:true})

2.修改 base href:

<script>document.write('<base href="' + document.location + '" />');</script>

于是乎,这时我们有两个选择:

  1. 重写 HashLocationStrategy,如下 issue 12341 所说:The router HashLocationStrategy should not use the History API
  2. 使用 HTTP 服务器来运行本地的 WebView 资源文件。

方式一,面对的主要挑战是,不只 Angular 使用 History API 来处理 hash 路由,其它框架也使用了相似的东西,如 React Router、Vue Router。

方式二,面对的主要问题是,我们需要在 Android 设备上启动一个 HTTP 服务器,并能让它支持跨域请求和访问本地文件。

在这个过程中,想到了 Ionic 框架也是使用 Angular 来编写的。于是,先运行了个官方的 Hello, world,发现它是运行在 http://localhost:8100 上的。

紧接着,复制了官方的 WebView 插件代码:Ionic Web View for Cordova。随之,我们就遇到了跨域的问题,原因是这些请求都是通过 WebView 发出去。

而这个问题,又近乎无解,我们无法获取 WebView post 请求中的参数。于是乎,我们只能通过插件来向 WebView 提供一个跨域请求的能力:Cordova Advanced HTTP

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806
comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Engineer, Consultant, Writer, Designer

ThoughtWorks 技术专家

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 最新技术分享

标签