ATSで許可されていないhttpなURLへの対処方法
August 06, 2017
前置き
iOS では ATS(App Transport Security)で許可されていない http リソースにはアクセスできない仕組みになっており、 React Native でもそれは変わりません。
自身が管理しているドメインであれば https にする、または 特定の限られた http リソース(かつ信頼できる)であれば ATS を許可する、 などやり方はありますが、 今回不特定の http リソースにアクセスする方法を実現したかったのでちょっと調べました。
環境は React Native 0.44、iOS での利用を想定してます。
方法
WebView
にonError
という props を渡すことで、
ネットワークに繋がっていないなどのエラー時に任意の関数を呼べます。
関数の引数としてエラー情報が入ったProxy
オブジェクトが返ってくるので、
それを使って外部ブラウザで開いたりすると良さそうです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 外部ブラウザで開く例 | |
import React, { Component } from 'react' | |
import { Alert, Linking, WebView } from 'react-native' | |
const ATS_ERROR_CODE = -1022 | |
export default class WebViewSample extends Component { | |
constructor(props) { | |
super(props) | |
this.handleError = this.handleError.bind(this) | |
this.openUrl = this.openUrl.bind(this) | |
} | |
handleError(proxy) { | |
const { code } = proxy.nativeEvent | |
const { url } = this.props | |
if (code === ATS_ERROR_CODE) { | |
this.openUrl(url) | |
} | |
} | |
openUrl(url) { | |
Linking.canOpenURL(url).then(supported => { | |
if (supported) { | |
Linking.openURL(url) | |
} else { | |
Alert.alert('URLを開けませんでした。') | |
} | |
}) | |
} | |
render() { | |
const { url } = this.props | |
return <WebView source={{ uri: url }} startInLoadingState onError={this.handleError} /> | |
} | |
} |
おわりに
外部ブラウザで開きたくないという場合は、 今回試してはいないですが naoufal/react-native-safari-view も使えそうです(しばらく更新されていないのは気がかりですが)。