从 Ionic Serve 调用远程服务

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

今天一位同事问了我一个有趣的问题:

我相信你在本地使用 IONIC SERVE 时可能遇到过这个错误。

XMLHttpRequest 无法加载 http://something.mybluemix.net/rest/audit/list。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问源“http://localhost:8100”。

本质上,我是通过工厂的 $http.get() 方法调用 URL。 Ionic 似乎有多种调用 REST 服务的方法(1.$http 或 2.ngResource)。

所以我的问题是,您是否有解决此问题的方法或从 Ionic 内部处理/调用 REST 服务的首选方式?任何示例代码将不胜感激。

这是一个很好的问题,因为有多种方法可以处理这个问题。在我们开始之前,让我们回顾一下。这个错误是什么,为什么我们会得到它?浏览器有一个安全模型,可以防止从一个域到另一个域的 Ajax 请求。这就是导致创建 JSON/P 的原因,它本质上是调用远程服务的一种变通方法。

使用 Cordova 时,您不必担心。但是当使用 Ionic Serve 并在浏览器中运行应用程序时,您必须想办法解决它。尽管使用 JSON/P 很简单,但我倾向于尝试避免将代码添加到我的 Cordova/Ionic 应用程序中,这些代码只是为了使其在桌面浏览器上运行。需要明确的是,我有时会这样做,但我尽量避免这样做。 (事实上​​,下面的答案之一将涉及这样的修改。)那么鉴于此,有哪些选择?

1)启用CORS
现代浏览器支持 CORS,这是远程 API 表示您的代码可以从另一个域调用它的一种方式。如果您有权访问 API(因此您正在构建移动端和服务器端),那么为您的 API 启用 CORS 是微不足道的。你如何做到这一点当然取决于语言。我描述了如何在 ColdFusion 中执行此操作,您可以使用 Node.js/Express 快速启用它。

2)用扩展破解
您可以找到一个 Chrome 扩展程序( 此处为它的超长 URL ),它将在您的应用程序中动态修改 CORS 标头。显然这只是 Chrome,但我喜欢它在任何地方都可以零更改工作。

3) 离子服务代理
你知道 Ionic Serve 本身有代理功能吗?在他们的 Testing in a Browser 文档页面中,他们讨论了如何修改 ionic.project 文件中的设置以添加代理。这是一个例子。


 {
  "name": "appname",
  "email": "",
  "app_id": "",
  "proxies": [
    {
      "path": "/v1",
      "proxyUrl": "https://api.instagram.com/v1"
    }
  ]
}

完成后,对 /v1 的请求将通过代理在本地重定向到 api.instagram.com/v1。这是一个很酷的功能,但它确实意味着您的代码必须更改。请注意,您可以通过检查浏览器平台(如此处所述 - 平台类 )或使用 ionic.Platform 来稍微简化这一过程。 哎呀,刮那个! 我很自然地假设如果添加 CSS 元素来标记浏览器平台,那么 ionic.Platform 也会支持它,但据我所知它不支持。我为此提交了 问题 4306

注意——我对此做了一些快速测试,基本上是 console.logging:


 {
  "name": "appname",
  "email": "",
  "app_id": "",
  "proxies": [
    {
      "path": "/v1",
      "proxyUrl": "https://api.instagram.com/v1"
    }
  ]
}

奇怪的是,在 Ionic 的运行块中,甚至在 $ionicPlatform.ready 中,该类也不存在。它只存在于我的第一个控制器中。这似乎……对我来说是错误的。

好的,所以更多的测试。在 ionic.Platform 的文档中,他们提到了一个平台数组。你可以这样做: ionic.Platform.platforms.contains("browser") 看看你是否在浏览器上。所以我的issue 4306有点不对。您可以检查 - 但似乎 isBrowser 辅助实用程序应该可用。

所以——总结一下——你有多种不同的处理方式——有些需要对代码进行一些更改,有些则不需要。找到最适合您的那一款,然后顺其自然。