使用實(shí)例
1聪建、使用get方式進(jìn)行網(wǎng)絡(luò)請求略贮,例如:
fetch('http://nero-zou.com/test', {
method: 'GET'
}).then(function(response) {
//獲取數(shù)據(jù),數(shù)據(jù)處理
}).catch(function(err) {
//錯誤處理
});
2氧腰、使用post方式進(jìn)行網(wǎng)絡(luò)請求,例如:
let param = {user:'xxx',phone:'xxxxxx'};
fetch(url, {
method: 'post',
body: JSON.stringify(param)
}).then(function(response) {
//獲取數(shù)據(jù),數(shù)據(jù)處理
});
3刨肃、其它寫法,例如:
try {
fetch(url, {
method: 'post',
body: JSON.stringify(param)
}).then(function(response) {
//獲取數(shù)據(jù),數(shù)據(jù)處理
});
} catch(e) {
//捕獲異常消息
}
4箩帚、帶header 或其它參數(shù)
fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
怎樣進(jìn)行封裝
基本上要求是寫個基礎(chǔ)的函數(shù),其它在進(jìn)行網(wǎng)絡(luò)請求時都調(diào)用這個函數(shù)真友。即使以后不使用fetch直接將這個基礎(chǔ)函數(shù)修改,不用修改其它的地方就可以實(shí)現(xiàn)紧帕。
基礎(chǔ)函數(shù)的模型一般是這樣的
function sendNetRequest(...props) {
this.url = props.shift(1);
this.options = props.shift(1);
return fetch(this.url, Object.assign({}, this.options))
.then((response) =>return response.json());
}
封裝各個接口
//封裝login 接口
function postLogin(userName,password) {
let loginParam= {user:userName,password:password};
var loginApiPort = "mlogin";//login 對應(yīng)的接口
//下面的baseURL=https://XXXXX.com
return sendNetRequest(`${baseURL}/${loginApiPort}`, {
method: 'post',
body: JSON.stringify(loginParam),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
}
//...其它一系列接口的封裝
調(diào)用實(shí)例
try {
postLogin(user,password)
.then((response) => {
//獲取數(shù)據(jù),數(shù)據(jù)處理
})
} catch(e) {
//捕獲異常消息
}
這樣就大功告成了盔然,下面是遇到的常見問題
常見問題
1桅打、請求時,出現(xiàn)異常
將header
里面的Content-Type
設(shè)置為‘a(chǎn)pplication/x-www-form-urlencoded’
愈案,如果還是報(bào)錯問server端參數(shù)是什么格式 挺尾,然后設(shè)置Content-Type
的值即可.
2、響應(yīng)時站绪,出現(xiàn)異常
上述封裝容易出現(xiàn)的問題在response.json()
這一句中遭铺,如果response==null
就會拋出異常,建議先判斷response
是否為null
恢准,如果為null
再進(jìn)行特殊處理魂挂。
3、fetch設(shè)置超時的時間
fetch
本身目前沒有設(shè)置超時時間的屬性馁筐,只能機(jī)制來進(jìn)行設(shè)置涂召。fetch
函數(shù)在各個平臺的實(shí)現(xiàn),如果你看到源代碼的話肯定會覺得能設(shè)置超時而且很容易敏沉,但是它封裝的時候并沒有把 這個作為一個屬性來設(shè)置.因此只能結(jié)合promise
機(jī)制使用setTimeout
來設(shè)置超時的時間果正。
4、https盟迟,如果server端是無效證書來進(jìn)行https請求的時候出現(xiàn)的錯誤
SSLHandshake: Received fatal alert: certificate_expired
或者是
SSLHandshake: Remote host closed connection during handshake
…
(1)在android暫時無解 秋泳,只能用http,因?yàn)樗荒芨淖儙炖锩娴暮瘮?shù)队萤。如果非要支持https 轮锥,只能將你的工程目錄 + node_modules/react-native/android/com/facebook/react/react-native/0.36.0/react-native-0.36.0-sources.jar!/com/facebook/react/modules/network/OkHttpClientProvider.java
,
其他rn版本的文件目錄可以推測要尔,總的來說是修改reactnative
的network
庫里面的OkHttpClientProvider.Java
這個文件舍杜。OkHttpClientProvider.java
中找到下述代碼
return new OkHttpClient.Builder()
.connectTimeout(0, TimeUnit.MILLISECONDS)
.readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS)
.cookieJar(new ReactCookieJarContainer())
.build();
改為:
return new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory())
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true; //忽略所有的認(rèn)證,直接返回了true
}
})
.connectTimeout(0, TimeUnit.MILLISECONDS)
.readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS)
.cookieJar(new ReactCookieJarContainer())
.build();
(2)iOS 端 赵辕,用xcode打開ios目錄下的工程既绩,找到infor.plist,并添加屬性
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
肯定還是報(bào)錯 还惠,找到React native的networking 庫(Libraries -> RCTNetworking -> RCTHTTPRequestHandler.mm -> #pragma mark NSURLSession delegate)饲握,在庫里面添加NSURLSession delegate
函數(shù)處理ssl證書認(rèn)證的相關(guān)代碼,設(shè)置為都為pass蚕键,你可以根據(jù)是否是debug模式來選擇是不是pass 救欧,如果是release 版建議不要這樣做。
如這個函數(shù)
//根據(jù)你自己的邏輯處理這個函數(shù)锣光,加點(diǎn)判斷千萬別直接pass,有安全隱患,如果都pass了還不如用http省的麻煩笆怠。
//只要請求的地址是HTTPS的, 就會調(diào)用這個代理方法
//challenge:質(zhì)詢
//NSURLAuthenticationMethodServerTrust:服務(wù)器信任
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
NSLog(@"%@",challenge.protectionSpace);
if (![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) return;
/*
NSURLSessionAuthChallengeUseCredential 使用證書
NSURLSessionAuthChallengePerformDefaultHandling 忽略證書 默認(rèn)的做法
NSURLSessionAuthChallengeCancelAuthenticationChallenge 取消請求,忽略證書
NSURLSessionAuthChallengeRejectProtectionSpace 拒絕,忽略證書
*/
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
}
實(shí)例
BaseServiceApiNet.js文件
const baseURL = "https://api.app.net";
function fetchAction(...props) {
this.url = props.shift(1);
this.options = props.shift(1);
return fetch(this.url, Object.assign({}, this.options))
.then((response) =>response.json());
}
export default {
getTest() {
var apiPort = "stream/0/posts/stream/global";
return fetchAction(`${baseURL}/${apiPort}`, {
method: 'get',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
}
};
index.ios.js文件
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ActivityIndicator
} from 'react-native';
import BaseServiceApiNet from './BaseServiceApiNet';
export default class ZXJNetDemo extends Component {
constructor(props){
super(props);
this.state ={
isLoading:false,
resultJson:null
};
}
sendTestRequest(){
if(this.state.isLoading==true){
return;
}
this.setState({
resultJson:null,
isLoading:true
});
try {
BaseServiceApiNet.getTest()
.then((response) => {
let data = response.meta;
this.setState({
resultJson:data==null?null:JSON.stringify(data),
isLoading:false
});
console.log("返回?cái)?shù)據(jù):"+JSON.stringify(data));
})
} catch(e) {
alert(e);
this.setState({
isLoading:false
});
}
}
render() {
return (
<View style={styles.container}>
<ActivityIndicator animating={this.state.isLoading} />
<Text style={styles.welcome} onPress={this.sendTestRequest.bind(this)}>
測試網(wǎng)絡(luò)
</Text>
<Text style={styles.instructions}>
{this.state.resultJson}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('ZXJNetDemo', () => ZXJNetDemo);
運(yùn)行結(jié)果
參考:
http://blog.csdn.net/qq_16086969/article/details/53522980#t11
http://www.cnblogs.com/liugengqun/p/5141482.html