从 ionic iOS 原生到 WP rest API 的 http 请求出错(适用于 web 视图和 DevApp)

Posted

技术标签:

【中文标题】从 ionic iOS 原生到 WP rest API 的 http 请求出错(适用于 web 视图和 DevApp)【英文标题】:Error on http requests from ionic iOS native to WP rest API (works on web view and DevApp) 【发布时间】:2019-09-03 10:10:18 【问题描述】:

我们正在尝试从我们的 ionic 应用程序向 Wordpress 服务器 (REST API) 发出 http 请求并收到以下错误: "_body":"isTrusted":true,"status":0,"ok":false,"statusText":"","headers":,"type":3,"url":null.

当我们使用 web 视图或 ionic DevApp 时请求工作正常,但在 ios 设备上失败。

到目前为止我们做了什么:

我们通过 DevApp 和 Web 视图验证了请求工作正常。 我们放宽了 cordova 白名单插件(请参阅下面的 config.xml)。 我们验证了我们的服务器上启用了 CORS(请参阅下面的 curl CORS 检查) 我们检查了在请求被阻止时没有从 iOS 设备发出 CORS 预检请求,因为我们可以在服务器访问日志上看到 GET 请求并且没有 OPTIONS 请求。 我们可以看到 GET 请求,显然设备与服务器之间存在连接。

如果您有任何建议,即使看起来有些牵强,我们也非常愿意倾听。

感谢您的帮助!

请求代码

import  Http, Response  from '@angular/http';

...

private requestData(path: String, params:Object = )
  return this.http.get( this.request.url + path, 
    params: 
      'consumer_key': this.conf.comm.appId,
      'consumer_secret': this.conf.comm.appSecret
    
  )
  .map( (res: Response) => this.prepareResponse(res) )
  .catch( (res: Response) => this.catchError(res) );

config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="app.c***r.***" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>***</name>
    <description>The ***</description>
    <author email="admin@c***r.app" href="https://c***r.app">***</author>
    <content src="index.html" />
    <access origin="*" />
    <access origin="*" subdomains="true" />
    <allow-navigation href="http://*/*" />
    <allow-navigation href="https://*/*" />
    <allow-navigation href="localhost:8080" />
    <allow-navigation href="data:*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="mailto:*" />
    <preference name="ScrollEnabled" value="false" />
    <preference name="android-minSdkVersion" value="19" />
    <preference name="BackupWebStorage" value="none" />
    <preference name="SplashMaintainAspectRatio" value="true" />
    <preference name="FadeSplashScreenDuration" value="300" />
    <preference name="SplashShowOnlyFirstTime" value="false" />
    <preference name="SplashScreen" value="screen" />
    <preference name="SplashScreenDelay" value="3000" />
    <platform name="android">
        <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
        ...
        <splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
    </platform>
    <platform name="ios">
        <icon  src="resources/ios/icon/icon.png"  />
        ...
        <splash  src="resources/ios/splash/Default@2x~universal~anyany.png"  />
    </platform>
    <plugin name="cordova-plugin-whitelist" spec="1.3.3" />
    <plugin name="cordova-plugin-statusbar" spec="2.4.2" />
    <plugin name="cordova-plugin-device" spec="2.0.2" />
    <plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
    <plugin name="cordova-plugin-ionic-webview" spec="^3.0.0" />
    <plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
    <plugin name="cordova-sqlite-storage" spec="3.2.0" />
    <engine name="ios" spec="~4.5.5" />
    <engine name="android" spec="~7.1.4" />
</widget>

卷曲 CORS 检查

* Hostname was NOT found in DNS cache
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 18.224.***.***...
* Connected to p***r.app (18.224.***.***) port 443 (#0)
* successfully set certificate verify locations:
...
*        SSL certificate verify ok.
> GET /wp-json/wc/v2/products/categories?consumer_key=ck_3***2&consumer_secret=cs_0***b&per_page=100 HTTP/1.1
> User-Agent: curl/7.38.0
> Host: p***r.app
> Accept: */*
> Origin: http://localhost:8080
>
< HTTP/1.1 200 OK
< Date: Fri, 12 Apr 2019 14:44:43 GMT
* Server Apache is not blacklisted
< Server: Apache
< X-Powered-By: php/7.0.31
< X-Robots-Tag: noindex
< Link: <https://p***r.app/wp-json/>; rel="https://api.w.org/"
< X-Content-Type-Options: nosniff
< Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages
< Access-Control-Allow-Headers: Authorization, Content-Type
< X-WP-Total: 98
< X-WP-TotalPages: 1
< Cache-Control: public, max-age=2592000
< Allow: GET
< Access-Control-Allow-Origin: http://localhost:8080
< Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
< Access-Control-Allow-Credentials: true
< Vary: Origin
< X-Frame-Options: SAMEORIGIN
< Transfer-Encoding: chunked
< Content-Type: application/json; charset=UTF-8
<

【问题讨论】:

“失败”是什么意思? 我们在通过 web 视图和 DevApp 测试应用程序时得到了响应,但在我们编译它并在真实设备上尝试时没有响应(在这种情况下,我们得到了问题中提到的错误) .无论如何,我们找到了原因并正在修复它。完成后将更新答案。 【参考方案1】:

问题是由 ionic 发送 ionic://localhost 作为已编译应用程序时的来源引起的。 WP REST 通过rest_send_cors_headers 响应,它通过esc_url_raw 传递来源,并由于其协议而拒绝该 url。

要解决此问题,只需通过过滤器 kses_allowed_protocols 将协议 ionic 添加到允许的协议列表中。

顺便说一句,如果您来自 ionic 并正在阅读本文,请考虑使编译后的应用程序的行为尽可能接近 Web 视图和 DevApp,包括发送到服务器的源。

【讨论】:

我遇到了同样的问题。您能否澄清一下我将在哪里找到允许的协议列表以添加离子协议? (我是新手) 请尽快回复我。这个问题太令人沮丧了。 您需要在 WP 上订阅 kses_allowed_protocols 并将 ionic 添加为已批准的协议。如果您不熟悉这些主题,我建议您使用谷歌搜索 CORS 和 WP hooks。 感谢您的帮助!这些链接非常有用,我现在已经解决了这个问题。【参考方案2】:

这是我在看到上面有用的答案后使用的代码。发布以防其他人正在寻找相同的解决方案。这可以在你的主题中的functions.php中或任何方便的地方。

add_filter('kses_allowed_protocols', function($protocols) 
    $protocols[] = 'ionic';
    return $protocols;
);

【讨论】:

$protocols[] = '电容器';万一你在电容器上

以上是关于从 ionic iOS 原生到 WP rest API 的 http 请求出错(适用于 web 视图和 DevApp)的主要内容,如果未能解决你的问题,请参考以下文章

在角度(离子)上的wp rest api中获取帖子绑定到id

从 localhost 到 rest api 的身份验证结果 CORS 错误

如何使用 REST_API wordpress 创建用户?

在 Ionic 中将 Android 和 iOS 原生代码 SDK 暴露给 Javascript

ionic3页面跳转动画安卓是上下滑动,ios是左右滑动,怎么能做到统一左右滑动呢?

如何在 Ionic Application 中使用原生 iOS/Android 地图?