解决方案:Proxy + CORS
为了节省大家的时间,废话不多说直接上代码
1.首先我们需要在 pubspec.yaml 引入 shelf_proxy:
dev_dependencies:
shelf_proxy: ^1.0.0
2.在lib目录创建 proxy.dart
import 'dart:io';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_proxy/shelf_proxy.dart';
final String target = 'http://api.test.com/'; // api地址
final String imgTarget = 'https://img.test.com/'; // 图片地址
void configServer(HttpServer server) {
// 这里设置请求策略,允许所有
server.defaultResponseHeaders.add('Access-Control-Allow-Origin', '*');
server.defaultResponseHeaders.add('Access-Control-Allow-Credentials', true);
server.defaultResponseHeaders.add('Access-Control-Allow-Methods', '*');
server.defaultResponseHeaders.add('Access-Control-Allow-Headers', '*');
server.defaultResponseHeaders.add('Access-Control-Max-Age', '3600');
}
void main() async {
var reqHandle = proxyHandler(target);
var imgHandle = proxyHandler(imgTarget);
/// 绑定本地端口,4500,转发到真正的服务器中
var server = await shelf_io.serve(reqHandle, 'localhost', 4500);
var imgServer = await shelf_io.serve(imgHandle, 'localhost', 4501);
configServer(server);
configServer(imgServer);
print('Api Serving at http://${server.address.host}:${server.port}');
print('Img Serving at http://${imgServer.address.host}:${imgServer.port}');
}
-
运行代理服务器
dart proxy.dart -
设置请求的BaseUrl为 http://localhost:4500 , 图片的BaseUrl为 http://localhost:4501
-
在web/index.html的
<head></head>标签内添加<meta name="referrer" content="never">防止图片403 -
测试
ajax.dart
import 'package:dio/dio.dart';
import 'request_interceptor.dart';
import 'log_interceptor.dart';
class Ajax {
final String baseUrl = '';
late Dio _dio;
Ajax._init() {
init();
}
static final Ajax _ajax = Ajax._init();
factory Ajax() {
return _ajax;
}
void init({bool debug = false}) async {
var _options = BaseOptions(
baseUrl: debug ? 'http://localhost:4500' : 'https://api.test.com',
contentType: Headers.formUrlEncodedContentType,
receiveTimeout: 10 * 1000,
connectTimeout: 10 * 1000,
);
_dio = Dio(_options);
_dio.interceptors.add(RequestInterceptor());
_dio.interceptors.add(MyLogInterceptor());
}
Future<Response<T>> send<T>(
String path, {
String method = 'GET',
data,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
Options? options,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) {
return _dio.request(
path,
options: Options(method: method),
queryParameters: queryParameters,
data: data,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
cancelToken: cancelToken,
);
}
}
main.dart
void main() {
Ajax().init(debug: true);
Ajax().send('/api/test', method: 'POST', data: data)
.then((res) {})
.catch((e) {})
runApp(MyApp());
}