Fetch 源码
- react-native/Libraries/Network/fetch.js
import 'whatwg-fetch'
module.exports = {fetch, Headers, Request, Response}
https:
line: 506
export function fetch(input, init) {
return new Promise(function(resolve, reject) {
var request = new Request(input, init)
...
}
}
- react-native/Libraries/Network/XMLHttpRequest.js
withCredentials: boolean = true
send(data: any): void {
...
RCTNetworking.sendRequest(
this._method,
this._trackingName,
this._url,
this._headers,
data,
nativeResponseType,
incrementalEvents,
this.timeout,
this.__didCreateRequest.bind(this),
this.withCredentials
);
}
ios: RCTNetworking.ios.js
android: RCTNetworking.android.js
- react-native/Libraries/Network/RCTNetworking.ios.js
sendRequest(
method: string,
trackingName: string,
url: string,
headers: Object,
data: RequestBody,
responseType: 'text' | 'base64',
incrementalUpdates: boolean,
timeout: number,
callback: (requestId: number) => any,
withCredentials: boolean
) {
const body = convertRequestBody(data);
RCTNetworkingNative.sendRequest({
method,
url,
data: {...body, trackingName},
headers,
responseType,
incrementalUpdates,
timeout,
withCredentials
}, callback);
}
其中: RCTNetworkingNative是在RCTNetworking.mm文件
- react-native/Libraries/Network/RCTNetworking.mm
RCT_EXPORT_METHOD(sendRequest:(NSDictionary *)query
responseSender:(RCTResponseSenderBlock)responseSender)
{
[self buildRequest:query completionBlock:^(NSURLRequest *request) {
NSString *responseType = [RCTConvert NSString:query[@"responseType"]];
BOOL incrementalUpdates = [RCTConvert BOOL:query[@"incrementalUpdates"]];
[self sendRequest:request
responseType:responseType
incrementalUpdates:incrementalUpdates
responseSender:responseSender];
}];
}
其中:
- (RCTURLRequestCancellationBlock)buildRequest:(NSDictionary<NSString *, id> *)query
completionBlock:(void (^)(NSURLRequest *request))block
{
RCTAssertThread(_methodQueue, @"buildRequest: must be called on method queue");
NSURL *URL = [RCTConvert NSURL:query[@"url"]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = [RCTConvert NSString:RCTNilIfNull(query[@"method"])].uppercaseString ?: @"GET";
NSArray<NSHTTPCookie *> *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:URL];
request.allHTTPHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
NSDictionary *headers = [RCTConvert NSDictionary:query[@"headers"]];
[headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
if (value) {
[request addValue:[RCTConvert NSString:value] forHTTPHeaderField:key];
}
}];
request.timeoutInterval = [RCTConvert NSTimeInterval:query[@"timeout"]];
request.HTTPShouldHandleCookies = [RCTConvert BOOL:query[@"withCredentials"]];
NSDictionary<NSString *, id> *data = [RCTConvert NSDictionary:RCTNilIfNull(query[@"data"])];
NSString *trackingName = data[@"trackingName"];
if (trackingName) {
[NSURLProtocol setProperty:trackingName
forKey:@"trackingName"
inRequest:request];
}
return [self processDataForHTTPQuery:data callback:^(NSError *error, NSDictionary<NSString *, id> *result) {
if (error) {
RCTLogError(@"Error processing request body: %@", error);
return (RCTURLRequestCancellationBlock)nil;
}
request.HTTPBody = result[@"body"];
NSString *dataContentType = result[@"contentType"];
NSString *requestContentType = [request valueForHTTPHeaderField:@"Content-Type"];
BOOL isMultipart = [dataContentType hasPrefix:@"multipart"];
if (dataContentType && ([requestContentType length] == 0 || isMultipart)) {
[request setValue:dataContentType forHTTPHeaderField:@"Content-Type"];
}
if ([request.allHTTPHeaderFields[@"Content-Encoding"] isEqualToString:@"gzip"]) {
request.HTTPBody = RCTGzipData(request.HTTPBody, -1 );
[request setValue:(@(request.HTTPBody.length)).description forHTTPHeaderField:@"Content-Length"];
}
dispatch_async(self->_methodQueue, ^{
block(request);
});
return (RCTURLRequestCancellationBlock)nil;
}];
}
- (void)sendRequest:(NSURLRequest *)request
responseType:(NSString *)responseType
incrementalUpdates:(BOOL)incrementalUpdates
responseSender:(RCTResponseSenderBlock)responseSender
{
...
task = [self networkTaskWithRequest:request completionBlock:completionBlock];
[task start];
...
}
- (RCTNetworkTask *)networkTaskWithRequest:(NSURLRequest *)request completionBlock:(RCTURLRequestCompletionBlock)completionBlock
{
id<RCTURLRequestHandler> handler = [self handlerForRequest:request];
if (!handler) {
RCTLogError(@"No suitable URL request handler found for %@", request.URL);
return nil;
}
RCTNetworkTask *task = [[RCTNetworkTask alloc] initWithRequest:request
handler:handler
callbackQueue:_methodQueue];
task.completionBlock = completionBlock;
return task;
}
- react-native/Libraries/Network/RCTNetworkTask.m
NSURLRequest
其他:
- 在iOS的主工程中只需要使用 NSHTTPCookieStorage
这个的文档很多
NSHTTPCookieStorage *Cookie = [NSHTTPCookieStorage sharedHTTPCookieStorage]
[Cookie setCookie:(NSHTTPCookie *)cookie]
[Cookie deleteCookie:(NSHTTPCookie *)cookie]