cordova ios 6.1.0 wkwebview 一些 xhr POST 失败
cordova ios 6.1.0 wkwebview some xhr POST fails
随着每个人的发展。使用离子堆栈,由于 Apple 的要求,我们也正在迁移到新的 wkwebview。
我们已经在没有任何警告(关于 uiwebview 旧代码)的情况下为 ios 提供了构建,但是我们在执行一些 POST 调用时仍然遇到问题。
设置
我们已经像下面这样设置了cors服务器端(Apache):
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>com.hrd.auth.tomcat7.cors.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>app://myapp, http://localhost:9090</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,Accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,User-Agent,DEVICE_ID</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<!-- <init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param> -->
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
下面改为当前APP配置:
<description>An app from company S.r.l.</description>
<author email="sviluppo@mycompany.com" href="https://www.mycompany.com/"> Contact us </author>
<content src="index.html" />
<!-- Permissions -->
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<!-- Preferences -->
<preference name="webviewbounce" value="false" />
<preference name="KeyboardResize" value="false" />
<preference name="BackupWebStorage" value="none" />
<preference name="DisallowOverscroll" value="true" />
<preference name="AutoHideSplashScreen" value="true" />
<preference name="StatusBarStyle" value="lightcontent" />
<preference name="ShowSplashScreenSpinner" value="false" />
<preference name="FadeSplashScreenDuration" value="1500" />
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="KeyboardDisplayRequiresUserAction" value="false"/>
<!-- Hooks -->
<hook src="www/hooks/fwk-after-prepare-hooks.js" type="after_prepare" />
<hook src="www/hooks/fwk-after-plugin-add-hooks.js" type="after_plugin_add" />
<hook src="www/hooks/fwk-after-prepare-copy-build-extra-hooks.js" type="after_prepare" />
<hook src="www/hooks/fwk-after-compile-hooks.js" type="after_compile" />
<hook src="www/hooks/fwk-before-build-hooks.js" type="before_build" />
<!-- iOS -->
<platform name="ios">
<!-- CORS -->
<preference name="scheme" value="app" />
<preference name="iosScheme" value="app" />
<preference name="hostname" value="myapp" />
<!-- Resouces -->
<resource-file src="www/GoogleService-Info.plist" />
<icon height="20" src="www/res/icon/ios/Icon-20.png" width="20" />
...
</platform>
<!-- PLUGINS LIST -->
<!-- LIST -->
<!-- Don't modify this plugins list because it's generate-->
<plugin name="cordova-plugin-app-version" spec="0.1.9"/>
<plugin name="cordova-plugin-calendar" spec="4.6.0"/>
<plugin name="cordova-plugin-call-number" spec="1.0.1"/>
<plugin name="cordova-plugin-camera" spec="4.1.0">
<variable name="CAMERA_USAGE_DESCRIPTION" value="Allow_the_app_to_use_your_camera" />
<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="Allow_the_app_to_access_your_photos" />
</plugin>
<plugin name="cordova-plugin-compat" spec="1.2.0"/>
<plugin name="cordova-plugin-device" spec="1.1.7"/>
<plugin name="cordova-plugin-facebook4" spec="6.2.0">
<variable name="APP_ID" value="2553981324652029" />
<variable name="APP_NAME" value="com.mycompany.myapp" />
</plugin>
<plugin name="cordova-plugin-file" spec="6.0.2"/>
<plugin name="cordova-plugin-inappbrowser" spec="4.0.0"/>
<plugin name="cordova-plugin-ionic-keyboard" spec="2.2.0"/>
<plugin name="cordova-plugin-media-capture" spec="3.0.3">
<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="Allow_the_app_to_access_your_photos" />
</plugin>
<plugin name="cordova-plugin-network-information" spec="1.3.4"/>
<plugin name="cordova-plugin-splashscreen" spec="5.0.3"/>
<plugin name="cordova-plugin-statusbar" spec="2.4.2"/>
<plugin name="cordova-plugin-whitelist" spec="1.3.3"/>
<plugin name="cordova-plugin-sign-in-with-apple" spec="0.1.0"/>
<plugin name="cordova-plugin-wkwebview-inject-cookie" spec="1.0.6"/>
<engine name="ios" spec="6.1.0" />
问题
APP成功POST调用登录,xhr详情如下
"{\"method\":\"POST\",
\"post\":\"{
\\"username\\":\\"username\\",
\\"password\\":\\"password\\"
}\",
\"url\":\"http://192.168.1.129:8080/go/rest/security/appLogin/MY_APP_LOGIN\",
\"headers\":{\"Content-Type\":\"application/json\",
\"DEVICE_ID\":\"a91d602c140079f2e848f39e33a6ca88\",
\"Accept\":\"application/json,text/plain,*/*\"},
\"withCredentials\":true}"
但是,在此调用中(在经过身份验证后执行)失败:
"{\"method\":\"POST\",
\"post\":\"{
\\"test\\":\\"test\\"
}\",
\"url\":\"http://192.168.1.129:8080/go/rest/security/userInfo\",
\"headers\":{
\"Accept\":\"application/json,text/plain,*/*\",
\"Content-Type\":\"application/json;charset=utf-8\"
},
\"withCredentials\":true}"
环境配置
- ionic-bundle 包含以下堆栈
** ionic.js 1.3.2
** angularJS 1.5.3
- 科尔多瓦 9.0.0
- 科尔多瓦-ios 6.1.0
有人知道为什么这种调用会失败吗?
常见问题解答
- 与第一个(登录调用)不同,第二个未到达服务器 CorsFilter.java class,因此调用“不退出 APP”
- 我们的 widget 环境与移动环境不同,已针对 POST 调用进行了修复,只是将调用有效负载模拟数据放入内部,以抱怨 w3c 浏览器规范。
非常感谢
西蒙
我们发现有关调用未到达服务器 CorsFilters.java class 的问题(因此无法获得一些调试实例)。
阅读我们的服务器日志,我们发现了这一行
192.168.x.x - - [02/Sep/2020:17:40:09 +0200] "OPTIONS /go/rest/security/userInfo HTTP/1.1" 401 7361 4286
这是一个关于预检 POST 请求的众所周知的问题 - 我们只需在我们的 web.xml conf 中添加。提交以下 属性
<web-resource-collection>
<web-resource-name>REST</web-resource-name>
<description>REST services</description>
<url-pattern>/rest/*</url-pattern>
<http-method-omission>OPTIONS</http-method-omission> <<--- add this row
</web-resource-collection>
这样,所有的 OPTIONS 请求都会被接受而不是被拒绝!
希望这对头痛一周的人有所帮助;)
西蒙
随着每个人的发展。使用离子堆栈,由于 Apple 的要求,我们也正在迁移到新的 wkwebview。
我们已经在没有任何警告(关于 uiwebview 旧代码)的情况下为 ios 提供了构建,但是我们在执行一些 POST 调用时仍然遇到问题。
设置
我们已经像下面这样设置了cors服务器端(Apache):
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>com.hrd.auth.tomcat7.cors.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>app://myapp, http://localhost:9090</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,Accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,User-Agent,DEVICE_ID</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<!-- <init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param> -->
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
下面改为当前APP配置:
<description>An app from company S.r.l.</description>
<author email="sviluppo@mycompany.com" href="https://www.mycompany.com/"> Contact us </author>
<content src="index.html" />
<!-- Permissions -->
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<!-- Preferences -->
<preference name="webviewbounce" value="false" />
<preference name="KeyboardResize" value="false" />
<preference name="BackupWebStorage" value="none" />
<preference name="DisallowOverscroll" value="true" />
<preference name="AutoHideSplashScreen" value="true" />
<preference name="StatusBarStyle" value="lightcontent" />
<preference name="ShowSplashScreenSpinner" value="false" />
<preference name="FadeSplashScreenDuration" value="1500" />
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="KeyboardDisplayRequiresUserAction" value="false"/>
<!-- Hooks -->
<hook src="www/hooks/fwk-after-prepare-hooks.js" type="after_prepare" />
<hook src="www/hooks/fwk-after-plugin-add-hooks.js" type="after_plugin_add" />
<hook src="www/hooks/fwk-after-prepare-copy-build-extra-hooks.js" type="after_prepare" />
<hook src="www/hooks/fwk-after-compile-hooks.js" type="after_compile" />
<hook src="www/hooks/fwk-before-build-hooks.js" type="before_build" />
<!-- iOS -->
<platform name="ios">
<!-- CORS -->
<preference name="scheme" value="app" />
<preference name="iosScheme" value="app" />
<preference name="hostname" value="myapp" />
<!-- Resouces -->
<resource-file src="www/GoogleService-Info.plist" />
<icon height="20" src="www/res/icon/ios/Icon-20.png" width="20" />
...
</platform>
<!-- PLUGINS LIST -->
<!-- LIST -->
<!-- Don't modify this plugins list because it's generate-->
<plugin name="cordova-plugin-app-version" spec="0.1.9"/>
<plugin name="cordova-plugin-calendar" spec="4.6.0"/>
<plugin name="cordova-plugin-call-number" spec="1.0.1"/>
<plugin name="cordova-plugin-camera" spec="4.1.0">
<variable name="CAMERA_USAGE_DESCRIPTION" value="Allow_the_app_to_use_your_camera" />
<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="Allow_the_app_to_access_your_photos" />
</plugin>
<plugin name="cordova-plugin-compat" spec="1.2.0"/>
<plugin name="cordova-plugin-device" spec="1.1.7"/>
<plugin name="cordova-plugin-facebook4" spec="6.2.0">
<variable name="APP_ID" value="2553981324652029" />
<variable name="APP_NAME" value="com.mycompany.myapp" />
</plugin>
<plugin name="cordova-plugin-file" spec="6.0.2"/>
<plugin name="cordova-plugin-inappbrowser" spec="4.0.0"/>
<plugin name="cordova-plugin-ionic-keyboard" spec="2.2.0"/>
<plugin name="cordova-plugin-media-capture" spec="3.0.3">
<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="Allow_the_app_to_access_your_photos" />
</plugin>
<plugin name="cordova-plugin-network-information" spec="1.3.4"/>
<plugin name="cordova-plugin-splashscreen" spec="5.0.3"/>
<plugin name="cordova-plugin-statusbar" spec="2.4.2"/>
<plugin name="cordova-plugin-whitelist" spec="1.3.3"/>
<plugin name="cordova-plugin-sign-in-with-apple" spec="0.1.0"/>
<plugin name="cordova-plugin-wkwebview-inject-cookie" spec="1.0.6"/>
<engine name="ios" spec="6.1.0" />
问题
APP成功POST调用登录,xhr详情如下
"{\"method\":\"POST\",
\"post\":\"{
\\"username\\":\\"username\\",
\\"password\\":\\"password\\"
}\",
\"url\":\"http://192.168.1.129:8080/go/rest/security/appLogin/MY_APP_LOGIN\",
\"headers\":{\"Content-Type\":\"application/json\",
\"DEVICE_ID\":\"a91d602c140079f2e848f39e33a6ca88\",
\"Accept\":\"application/json,text/plain,*/*\"},
\"withCredentials\":true}"
但是,在此调用中(在经过身份验证后执行)失败:
"{\"method\":\"POST\",
\"post\":\"{
\\"test\\":\\"test\\"
}\",
\"url\":\"http://192.168.1.129:8080/go/rest/security/userInfo\",
\"headers\":{
\"Accept\":\"application/json,text/plain,*/*\",
\"Content-Type\":\"application/json;charset=utf-8\"
},
\"withCredentials\":true}"
环境配置
- ionic-bundle 包含以下堆栈 ** ionic.js 1.3.2 ** angularJS 1.5.3
- 科尔多瓦 9.0.0
- 科尔多瓦-ios 6.1.0
有人知道为什么这种调用会失败吗?
常见问题解答
- 与第一个(登录调用)不同,第二个未到达服务器 CorsFilter.java class,因此调用“不退出 APP”
- 我们的 widget 环境与移动环境不同,已针对 POST 调用进行了修复,只是将调用有效负载模拟数据放入内部,以抱怨 w3c 浏览器规范。
非常感谢 西蒙
我们发现有关调用未到达服务器 CorsFilters.java class 的问题(因此无法获得一些调试实例)。
阅读我们的服务器日志,我们发现了这一行
192.168.x.x - - [02/Sep/2020:17:40:09 +0200] "OPTIONS /go/rest/security/userInfo HTTP/1.1" 401 7361 4286
这是一个关于预检 POST 请求的众所周知的问题 - 我们只需在我们的 web.xml conf 中添加。提交以下 属性
<web-resource-collection>
<web-resource-name>REST</web-resource-name>
<description>REST services</description>
<url-pattern>/rest/*</url-pattern>
<http-method-omission>OPTIONS</http-method-omission> <<--- add this row
</web-resource-collection>
这样,所有的 OPTIONS 请求都会被接受而不是被拒绝!
希望这对头痛一周的人有所帮助;)
西蒙