应用仅在iOS模拟器上卡在启动屏白屏 报JS MIME类型无效错误
Cordova iOS 模拟器启动白屏(JS MIME类型错误)解决方案
故障根因
该报错TypeError: 'application/octet-stream' is not a valid JavaScript MIME type.仅出现在iOS 14及以上版本模拟器,是因为WKWebView在模拟器环境下加载本地JS资源时,会错误识别文件MIME类型为application/octet-stream,而真机的本地资源MIME校验逻辑和模拟器存在差异,因此不会触发报错。
修复步骤
方案1:临时修改平台源码(不推荐,每次新增平台会被覆盖)
找到platforms/ios/CordovaLib/Classes/CDVWebViewEngine.m文件,定位到decidePolicyForNavigationResponse代理方法,在方法开头插入以下代码:// 修复模拟器JS文件MIME类型识别错误 if ([navigationResponse.response.MIMEType isEqualToString:@"application/octet-stream"] && [navigationResponse.response.URL.pathExtension.lowercaseString isEqualToString:@"js"]) { NSMutableDictionary *headers = [((NSHTTPURLResponse *)navigationResponse.response) allHeaderFields].mutableCopy; headers[@"Content-Type"] = @"application/javascript"; NSHTTPURLResponse *fixedResponse = [[NSHTTPURLResponse alloc] initWithURL:navigationResponse.response.URL statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headers]; navigationResponse = [WKNavigationResponse responseWithResponse:fixedResponse]; }方案2:用Cordova钩子自动注入修改(推荐,持久化生效)
- 在项目根目录创建
hooks/after_platform_add文件夹,新增文件fix_simulator_js_mime.js,写入以下内容:
const fs = require('fs'); const path = require('path'); module.exports = (context) => { const targetFilePath = path.join( context.opts.projectRoot, 'platforms', 'ios', 'CordovaLib', 'Classes', 'CDVWebViewEngine.m' ); if (!fs.existsSync(targetFilePath)) return; let fileContent = fs.readFileSync(targetFilePath, 'utf8'); const injectCode = ` // 修复模拟器JS文件MIME类型识别错误 if ([navigationResponse.response.MIMEType isEqualToString:@"application/octet-stream"] && [navigationResponse.response.URL.pathExtension.lowercaseString isEqualToString:@"js"]) { NSMutableDictionary *headers = [((NSHTTPURLResponse *)navigationResponse.response) allHeaderFields].mutableCopy; headers[@"Content-Type"] = @"application/javascript"; NSHTTPURLResponse *fixedResponse = [[NSHTTPURLResponse alloc] initWithURL:navigationResponse.response.URL statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headers]; navigationResponse = [WKNavigationResponse responseWithResponse:fixedResponse]; } `; const methodMatch = '- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {'; if (fileContent.indexOf(injectCode) === -1) { fileContent = fileContent.replace(methodMatch, `${methodMatch}${injectCode}`); fs.writeFileSync(targetFilePath, fileContent, 'utf8'); } };- 给钩子文件添加执行权限:
chmod +x hooks/after_platform_add/fix_simulator_js_mime.js
- 在项目根目录创建
第三步:添加配置项并重新构建
- 在项目
config.xml的<platform name="ios">节点下新增以下配置:
<preference name="AllowFileAccessFromFileURLs" value="true" /> <preference name="AllowUniversalAccessFromFileURLs" value="true" />- 清理旧构建产物并重新运行模拟器:
cordova clean ios cordova emulate ios- 在项目
验证方法
启动模拟器后打开Safari开发者工具,连接对应模拟器的应用页面,在「网络」面板查看所有JS资源的响应头,确认Content-Type字段为application/javascript即可。
内容的提问来源于stack exchange,提问作者crg
相关产品推荐
相关产品推荐

