Skip to content

Commit 8f2b5cb

Browse files
committed
Add support for POST header (crossOrigin mode)
1 parent 954c647 commit 8f2b5cb

File tree

6 files changed

+93
-1
lines changed

6 files changed

+93
-1
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,34 @@ resolve: {
1616
}
1717
```
1818

19+
Add the following rule to your webpack config:
20+
21+
```js
22+
const rule = {
23+
test: /postMock.html$/,
24+
use: {
25+
loader: 'file-loader',
26+
options: {
27+
name: '[name].[ext]',
28+
},
29+
},
30+
};
31+
```
32+
1933
## Usage
2034
```js
2135
import WebView from 'WebView'; // don't import from react-native
2236
```
2337

2438
See [RN's doc](https://facebook.github.io/react-native/docs/webview.html).
2539

40+
Supported props are:
41+
- source
42+
- uri
43+
- uri with POST header (this opens a new window)
44+
- html
45+
- onMessage
46+
2647
## Examples
2748
See the [storybook](https://react-native-web-community.github.io/react-native-web-webview/storybook).
2849

docs/stories/onMessage.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ <h1>Hello world!</h1>
1919
});
2020

2121
document.getElementById('button').addEventListener('click', function() {
22-
if (window.parent) {
22+
if (window.opener) {
23+
// Web new window
24+
window.opener.postMessage(payload, window.opener.origin);
25+
window.close();
26+
} else if (window.parent) {
2327
// Web iframe
2428
window.parent.postMessage(payload, window.parent.origin);
2529
} else {

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,8 @@
3939
},
4040
"peerDependencies": {
4141
"react-native-web": "*"
42+
},
43+
"dependencies": {
44+
"qs": "^6.5.1"
4245
}
4346
}

src/index.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import Qs from 'qs';
12
import React, { Component } from 'react';
3+
import { StyleSheet, View, ActivityIndicator } from 'react-native';
24

35
export default class extends Component {
46
constructor(props) {
@@ -7,11 +9,38 @@ export default class extends Component {
79
if (props.onMessage) {
810
window.addEventListener('message', this.onMessage, true);
911
}
12+
13+
if (props.source.method === 'POST') {
14+
const contentType = props.source.headers['Content-Type'];
15+
let body = '';
16+
if (contentType && contentType.includes('application/x-www-form-urlencoded')) {
17+
body = Qs.parse(props.source.body);
18+
} else {
19+
console.warn('[WebView] Content type is not supported yet, please make a PR!', contentType);
20+
return;
21+
}
22+
23+
window.open(
24+
require('./postMock.html') + '?' +
25+
Qs.stringify({
26+
uri: props.source.uri,
27+
body: JSON.stringify(body),
28+
})
29+
);
30+
}
1031
}
1132

1233
onMessage = nativeEvent => nativeEvent.isTrusted && this.props.onMessage({ nativeEvent });
1334

1435
render() {
36+
if (this.props.source.method === 'POST') {
37+
return (
38+
<View style={styles.loadingContainer}>
39+
<ActivityIndicator />
40+
</View>
41+
);
42+
}
43+
1544
return (
1645
<iframe
1746
src={this.props.source.uri}
@@ -25,3 +54,11 @@ export default class extends Component {
2554
);
2655
}
2756
}
57+
58+
const styles = StyleSheet.create({
59+
loadingContainer: {
60+
flex: 1,
61+
alignItems: 'center',
62+
justifyContent: 'center',
63+
},
64+
});

src/postMock.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<html>
2+
<body>
3+
<div id="content" style="display: none"></div>
4+
</body>
5+
<script>
6+
const source = new URLSearchParams(window.location.search);
7+
8+
let html = `<form method="POST" action="${source.get('uri')}">`;
9+
10+
const params = JSON.parse(source.get('body'));
11+
12+
Object.entries(params).forEach(([name, value]) => (html += `<input name="${name}" value="${value}" />`));
13+
14+
html +=
15+
"<input id='submit' type='submit' />" +
16+
"</form>";
17+
18+
const div = document.createElement('div');
19+
div.innerHTML = html;
20+
document.getElementById('content').appendChild(div);
21+
document.getElementById('submit').click();
22+
</script>
23+
</html>

yarn.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,6 +2124,10 @@ punycode@^1.2.4, punycode@^1.4.1:
21242124
version "1.4.1"
21252125
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
21262126

2127+
qs@^6.5.1:
2128+
version "6.5.1"
2129+
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
2130+
21272131
qs@~6.4.0:
21282132
version "6.4.0"
21292133
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"

0 commit comments

Comments
 (0)