Flutter Web开发代理服务器插件web_dev_proxy_shelf的使用
Flutter Web开发代理服务器插件web_dev_proxy_shelf的使用
一个实现了CORS和Cookie CORS的Web开发代理服务器,基于shelf_proxy。
特性
- 在Web开发中修改响应头和Cookie以支持CORS
入门指南
步骤1
在Dart文件中定义目标主机和本地代理主机及端口,类似于:
class LocalProxyConfig {
static String targetUrl = 'https://navi-api.xxx.tech';
static const String localHost = 'localhost';
static const int localPort = 8033;
static const String localProxyUrlWeb = "http://$localHost:$localPort";
}
步骤2
在另一个Dart文件中定义主方法:
import 'package:web_dev_proxy/src/shelf_proxy_for_web_dev.dart';
import 'proxy_web_local_config.dart';
Future<void> main() async {
await startLocalProxyServerForWebDebug(
LocalProxyConfig.localHost,
LocalProxyConfig.localPort,
LocalProxyConfig.targetUrl,
true);
}
步骤3
运行步骤2中的主方法
Proxying at http://localhost:8033 for https://navi-api.xxx.tech
步骤4
当平台为Web时,在项目中使用LocalProxyConfig.localProxyUrlWeb
作为基本URL。
代理做了什么?
修改响应头以允许请求CORS
类似于在Web发布时使用Nginx进行操作。
// 修改响应头
// 有时后台写了Access-Control-Allow-Origin,那么server.defaultResponseHeaders的设置就会无效
// if("OPTIONS" == (clientResponse?.request?.method??"")){
Map<String, String> headers = clientResponse.headers;
// 不能同时多个
headers.remove('access-control-allow-origin');
headers.remove('access-control-allow-methods');
headers.remove('access-control-allow-headers');
headers.remove('access-control-expose-headers');
headers.remove('access-control-max-age');
headers.remove('access-control-allow-credentials');
// 你请求什么,就允许什么
// access-control-request-headers 这个是chrome加了,所以在request!.headers里取不到
// Request header field app-version is not allowed by Access-Control-Allow-Headers in preflight response.
// Map<String, String> reqeustHeaders = clientResponse!.request!.headers!;
String headerStr = clientResponse!.request!
.headers['access-control-request-headers'].toString();
// 预检请求不会携带额外的header,所以下面拼接header没有鸟用, 要用access-control-request-headers取
// reqeustHeaders.forEach((key, value) { headerStr = headerStr+","+key; });
// access-control-request-headers
if (headerStr == "null") {
headerStr = "*";
}
clientResponse.headers['Access-Control-Allow-Headers'] = headerStr;
// clientResponse.headers['Access-Control-Allow-Headers'] = "*";//预检请求里,['Access-Control-Allow-Credentials'] = 'true'时 不能用*
clientResponse.headers['Access-Control-Allow-Methods'] = "*"; // GET,POST,PUT,OPTIONS
clientResponse.headers['Access-Control-Expose-Headers'] = headerStr;
clientResponse.headers['Access-Control-Max-Age'] = '36000'; // 如果chrome开启了禁用缓存,那么每次都会发预检请求
clientResponse.headers['Access-Control-Allow-Credentials'] = 'true';
// 预检请求: 设置了-Allow-Credentials'] = 'true'时,两个限制:
// Access-Control-Allow-Origin'] 不能为 "*" -Allow-Headers'] = "*"
// clientResponse.headers['Access-Control-Allow-Origin'] = "*";
String original = clientResponse!.request!.headers["Referer"].toString();
if(original == "null"){
original = "*";
}
if (original.endsWith("/")) {
original = original.substring(0, original.length - 1);
}
clientResponse.headers['Access-Control-Allow-Origin'] = original;
// The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
// The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
修改Set-Cookie头部
void transferCookies(http.StreamedResponse clientResponse, String localHost) {
String? cookie = clientResponse.headers['set-cookie'];
if (cookie == null || cookie.isEmpty) {
return;
}
// 服务器要发送多个 cookie,则应该在同一响应中发送多个 Set-Cookie 标头。
Cookie cookie2 = Cookie.fromSetCookieValue(cookie);
cookie2.secure = true;
cookie2.httpOnly = false;
cookie2.domain = localHost;
clientResponse.headers['set-cookie'] = cookie2.toString() + ";SameSite=None;";
print("reset set-cookie header from $cookie to \n ${clientResponse.headers['set-cookie']}\n");
}
更多关于Flutter Web开发代理服务器插件web_dev_proxy_shelf的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter Web开发代理服务器插件web_dev_proxy_shelf的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter Web开发中,有时我们需要代理请求来避免跨域问题或进行本地开发调试。web_dev_proxy_shelf
是一个用于 Flutter Web 开发的代理服务器插件,它基于 shelf
框架,允许你在开发过程中轻松地代理请求。
安装 web_dev_proxy_shelf
首先,你需要在 pubspec.yaml
文件中添加 web_dev_proxy_shelf
依赖:
dev_dependencies:
web_dev_proxy_shelf: ^0.1.0
然后运行 flutter pub get
来安装依赖。
使用 web_dev_proxy_shelf
-
创建代理服务器配置文件
在你的 Flutter 项目根目录下创建一个
webdev_proxy.yaml
文件,用于配置代理规则。例如:proxies: - path: /api target: https://api.example.com
在这个例子中,所有以
/api
开头的请求都会被代理到https://api.example.com
。 -
启动 Flutter Web 开发服务器
在终端中运行以下命令来启动 Flutter Web 开发服务器,并使用
web_dev_proxy_shelf
代理请求:flutter pub run web_dev_proxy_shelf
这将启动一个本地服务器,并应用你在
webdev_proxy.yaml
中配置的代理规则。 -
访问你的 Flutter Web 应用
启动服务器后,你可以通过
http://localhost:8080
访问你的 Flutter Web 应用。所有符合代理规则的请求都会被代理到指定的目标地址。
自定义端口和配置
你可以通过命令行参数来自定义端口和其他配置。例如:
flutter pub run web_dev_proxy_shelf --port=8081 --config=my_proxy_config.yaml
--port
:指定服务器监听的端口,默认为8080
。--config
:指定代理配置文件的路径,默认为webdev_proxy.yaml
。
示例项目结构
一个典型的项目结构可能如下所示:
my_flutter_web_project/
├── lib/
│ └── main.dart
├── web/
│ └── index.html
├── pubspec.yaml
├── webdev_proxy.yaml