diff --git a/Examples/UIExplorer/XHRExample.android.js b/Examples/UIExplorer/XHRExample.android.js
index 1dfb9a32cfe86c..5a46d8dd9751d3 100644
--- a/Examples/UIExplorer/XHRExample.android.js
+++ b/Examples/UIExplorer/XHRExample.android.js
@@ -28,6 +28,7 @@ var {
var XHRExampleHeaders = require('./XHRExampleHeaders');
var XHRExampleCookies = require('./XHRExampleCookies');
+var XHRExampleFetch = require('./XHRExampleFetch');
// TODO t7093728 This is a simplified XHRExample.ios.js.
@@ -281,6 +282,11 @@ exports.examples = [{
render() {
return ;
}
+}, {
+ title: 'Fetch Test',
+ render() {
+ return ;
+ }
}, {
title: 'Headers',
render() {
diff --git a/Examples/UIExplorer/XHRExample.ios.js b/Examples/UIExplorer/XHRExample.ios.js
index cc83ccf5837c0d..d8d370319aa864 100644
--- a/Examples/UIExplorer/XHRExample.ios.js
+++ b/Examples/UIExplorer/XHRExample.ios.js
@@ -31,6 +31,7 @@ var {
} = React;
var XHRExampleHeaders = require('./XHRExampleHeaders');
+var XHRExampleFetch = require('./XHRExampleFetch');
class Downloader extends React.Component {
@@ -304,54 +305,6 @@ class FormUploader extends React.Component {
}
}
-class FetchTest extends React.Component {
-
- constructor(props) {
- super(props);
- this.state = {
- responseText: null,
- };
- }
-
- submit(uri: String) {
- fetch(uri).then((response) => {
- return response.text();
- }).then((body) => {
- this.setState({responseText: body});
- });
- }
-
- render() {
-
- var response = this.state.responseText ? (
-
- Server response:
-
-
- ) : null;
-
- return (
-
- Edit URL to submit:
- {
- this.submit(event.nativeEvent.text);
- }}
- style={styles.textInput}
- />
- {response}
-
- );
- }
-}
-
exports.framework = 'React';
exports.title = 'XMLHttpRequest';
exports.description = 'XMLHttpRequest';
@@ -366,9 +319,9 @@ exports.examples = [{
return ;
}
}, {
- title: 'fetch test',
+ title: 'Fetch Test',
render() {
- return ;
+ return ;
}
}, {
title: 'Headers',
@@ -432,19 +385,4 @@ var styles = StyleSheet.create({
fontSize: 16,
fontWeight: '500',
},
- label: {
- flex: 1,
- color: '#aaa',
- fontWeight: '500',
- height: 20,
- },
- textOutput: {
- flex: 1,
- fontSize: 17,
- borderRadius: 3,
- borderColor: 'grey',
- borderWidth: 1,
- height: 200,
- paddingLeft: 8,
- },
});
diff --git a/Examples/UIExplorer/XHRExampleFetch.js b/Examples/UIExplorer/XHRExampleFetch.js
new file mode 100644
index 00000000000000..893dd75912012d
--- /dev/null
+++ b/Examples/UIExplorer/XHRExampleFetch.js
@@ -0,0 +1,112 @@
+/**
+ * The examples provided by Facebook are for non-commercial testing and
+ * evaluation purposes only.
+ *
+ * Facebook reserves all rights not expressly granted.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
+ * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * @flow
+ */
+'use strict';
+
+var React = require('react-native');
+var {
+ StyleSheet,
+ Text,
+ TextInput,
+ View,
+ Platform,
+} = React;
+
+
+class XHRExampleFetch extends React.Component {
+
+ constructor(props: any) {
+ super(props);
+ this.state = {
+ responseText: null,
+ };
+ this.responseURL = null;
+ }
+
+ submit(uri: String) {
+ fetch(uri).then((response) => {
+ this.responseURL = response.url;
+ return response.text();
+ }).then((body) => {
+ this.setState({responseText: body});
+ });
+ }
+
+ render() {
+
+ var responseURL = this.responseURL ? (
+
+ Server response URL:
+ {this.responseURL}
+
+ ) : null;
+
+ var response = this.state.responseText ? (
+
+ Server response:
+
+
+ ) : null;
+
+ return (
+
+ Edit URL to submit:
+ {
+ this.submit(event.nativeEvent.text);
+ }}
+ style={styles.textInput}
+ />
+ {responseURL}
+ {response}
+
+ );
+ }
+}
+
+var styles = StyleSheet.create({
+ textInput: {
+ flex: 1,
+ borderRadius: 3,
+ borderColor: 'grey',
+ borderWidth: 1,
+ height: Platform.OS === 'android' ? 44 : 30,
+ paddingLeft: 8,
+ },
+ label: {
+ flex: 1,
+ color: '#aaa',
+ fontWeight: '500',
+ height: 20,
+ },
+ textOutput: {
+ flex: 1,
+ fontSize: 17,
+ borderRadius: 3,
+ borderColor: 'grey',
+ borderWidth: 1,
+ height: 200,
+ paddingLeft: 8,
+ },
+});
+
+module.exports = XHRExampleFetch;
diff --git a/Libraries/Network/RCTNetworking.m b/Libraries/Network/RCTNetworking.m
index 6bbea21b1f27b6..74954199100277 100644
--- a/Libraries/Network/RCTNetworking.m
+++ b/Libraries/Network/RCTNetworking.m
@@ -375,7 +375,8 @@ - (void)sendRequest:(NSURLRequest *)request
headers = response.MIMEType ? @{@"Content-Type": response.MIMEType} : @{};
status = 200;
}
- NSArray *responseJSON = @[task.requestID, @(status), headers];
+ id responseURL = response.URL ? response.URL.absoluteString : [NSNull null];
+ NSArray *responseJSON = @[task.requestID, @(status), headers, responseURL];
[_bridge.eventDispatcher sendDeviceEventWithName:@"didReceiveNetworkResponse"
body:responseJSON];
});
diff --git a/Libraries/Network/XMLHttpRequestBase.js b/Libraries/Network/XMLHttpRequestBase.js
index 4cdc424721fbde..f4c8bc5e246abc 100644
--- a/Libraries/Network/XMLHttpRequestBase.js
+++ b/Libraries/Network/XMLHttpRequestBase.js
@@ -32,6 +32,7 @@ class XMLHttpRequestBase {
responseHeaders: ?Object;
responseText: ?string;
status: number;
+ responseURL: ?string;
upload: ?{
onprogress?: (event: Object) => void;
@@ -69,6 +70,7 @@ class XMLHttpRequestBase {
this.responseHeaders = undefined;
this.responseText = '';
this.status = 0;
+ delete this.responseURL;
this._requestId = null;
@@ -110,11 +112,16 @@ class XMLHttpRequestBase {
}
}
- _didReceiveResponse(requestId: number, status: number, responseHeaders: ?Object): void {
+ _didReceiveResponse(requestId: number, status: number, responseHeaders: ?Object, responseURL: ?string): void {
if (requestId === this._requestId) {
this.status = status;
this.setResponseHeaders(responseHeaders);
this.setReadyState(this.HEADERS_RECEIVED);
+ if (responseURL || responseURL === '') {
+ this.responseURL = responseURL;
+ } else {
+ delete this.responseURL;
+ }
}
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java
index 728acf7fe99f62..d1f32616e6a46b 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java
@@ -289,6 +289,7 @@ private void onResponseReceived(int requestId, Response response) {
args.pushInt(requestId);
args.pushInt(response.code());
args.pushMap(headers);
+ args.pushString(response.request().urlString());
getEventEmitter().emit("didReceiveNetworkResponse", args);
}