The problem comes from webkit which blocks the response because of cross domain origin request. Since we mock the response we have to force the Access-Control-Allow-Origin.
Then we also need to force the content-type of the response.
Here is where the magic happens :
NSDictionary *headers = @{@"Access-Control-Allow-Origin" : @"*", @"Access-Control-Allow-Headers" : @"Content-Type"};
NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:request.URL statusCode:200 HTTPVersion:@"1.1" headerFields:headers];
The final implementation of the protocol :
#import "EpubProtocol.h"
@implementation EpubProtocol
#pragma mark - NSURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
BOOL isAwsRequest = [self request:request contains:@"s3.amazonaws.com"];
return isAwsRequest;
}
+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)theRequest
{
return theRequest;
}
- (void)startLoading {
NSURLRequest *request = [self request];
//Mock Amazon call
if([EpubProtocol request:request contains:@"s3.amazonaws.com"]) {
NSString *path = [[NSBundle bundleForClass:self.class] pathForResource:@"epub1" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:path];
[self mockRequest:request data:data];
}
}
- (void)stopLoading
{
NSLog(@"Did stop loading");
}
#pragma mark - Request utils
+ (BOOL) request:(NSURLRequest*)request contains:(NSString*)domain {
NSString *str = [[request URL] absoluteString];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", domain];
return [pred evaluateWithObject:str];
}
#pragma mark - Mock responses
-(void) mockRequest:(NSURLRequest*)request data:(NSData*)data {
id client = [self client];
NSDictionary *headers = @{@"Access-Control-Allow-Origin" : @"*", @"Access-Control-Allow-Headers" : @"Content-Type"};
NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:request.URL statusCode:200 HTTPVersion:@"1.1" headerFields:headers];
[client URLProtocol:self didReceiveResponse:response
cacheStoragePolicy:NSURLCacheStorageNotAllowed];
[client URLProtocol:self didLoadData:data];
[client URLProtocolDidFinishLoading:self];
}
@end
Nothing special in the JS :
function loadJSONDoc()
{
var url = "https://s3.amazonaws.com/youboox_recette/epub.json";
$.ajax({
url: url,
dataType: 'json',
contentType: "application/json",
success: function(jsonData){
alert('success');
document.getElementById("myDiv").innerHTML='<p>'+$.param(jsonData)+'</p>';
},
error: function (request, status, error) {
alert("failure :" + request.status );
}
});
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…