Last Flutter2 for Web, I wrote a blog site that went live and we simply encapsulated the Web request. We are happy to run the project on Chrome, but do not see the data, through the developer tools, reported the following error:
This is a cross – domain error.
Our webpage address is http://localhost:62924, and then the page sent a request, and the interface domain name of the request is D6579fc5-C18b-443b-a2ef-01c2b6be51d5.bspapp.com, so their domain names are inconsistent, and there is cross-domain. It is protected by the same origin policy and therefore cannot interact with data.
What is cross-domain
If the protocol, domain name, and port are the same, it is considered to be in the same domain. If one of the three conditions is inconsistent, it is not considered to be in the same domain.
Even if it is our own domain name server, and the secondary domain name or the tertiary domain name is inconsistent, there will be cross-domain, such as: data interaction between http://img.loveli.site and http://blog.loveli.site, cross-domain.
All browsers now implement the same origin policy.
The same-origin policy was introduced in the browser by Netscape in 1995: when an Ajax request is sent, only data resources that are responded to by the same-domain server are received.
The purpose of the same origin policy is to ensure the security of user information and prevent malicious websites from stealing data.
Cross-domain solutions
How can data from two different domains interact smoothly? The most typical schemes in the early stage are:
- JSONP
- Sympatric agent
JSONP uses the SRC attribute of script tag to realize cross-domain data interaction, because when the browser parses THE HTML code, the browser gives the ability of HTTP request to tags with SRC attribute, and is not restricted by cross-domain, using SRC to send HTTP requests. The server directly returns a section of JS code function call, put the server data in the function argument, the front end of the response function written in advance ready to callback, receive data, to achieve cross-domain data interaction;
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type"."text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
Copy the code
Local proxy is to use Ajax to send requests to the background in the same domain, carrying the address and parameters of the real request. After receiving the request, the background directly forwards the request according to the address and parameters. Because the background can directly simulate the HTTP client to send requests, there is no cross-domain problem. The background receives the response data and then returns it to the front-end browser as is, so as to realize cross-domain data interaction.
JSONP and co-domain proxy, in essence, do not solve the problem of Ajax cross-domain, but bypass this problem and find a new way to achieve cross-domain data interaction, on the level of data interaction can be regarded as a temporary solution when the technology is not mature; However, JSONP and co-domain proxy have been used for many years, of course, cross-domain problems also exist for many years, finally someone can not look down, put forward the browser and server cross-domain communication security communication strategy ———— cross-domain resource sharing, referred to as CORS;
CORS (Online Solution)
CORS stands for Cross-Origin Resource Sharing. It is a W3C standard and a fundamental solution for cross-source AJAX requests.
CORS requires both browser and server support. Currently, all browsers support this feature. Therefore, the key to CORS communication is the server. As long as the server implements the CORS interface, cross-source communication is possible.
Because of the specificity of this article, we will not modify the server, so how the server implements CORS will not be explained. To learn more about CORS, read:
- Cross-domain resource sharing (CORS
- Cross-source Resource Sharing (CORS)
Request Forwarding (development scenario)
Since we don’t want to modify online servers, how do we solve cross-domain problems?
In fact, it is also simple, we locally implement proxy forwarding server, and configure CORS.
So let’s take you through it
Creating a CLI Project
How to create a CLI application?
-
Step 1 Install dart:
$ brew tap dart-lang/dart $ brew install dart Copy the code
-
Creating a CLI application:
$ dart create -t console-full cli Copy the code
Use the dart create command to create a CLI project using the console-full template
bin/cli.dart
, which contains a top-level main() function. This function is the entry point to your applicationlib/cli.dart
Dart contains some functional function methods that will be imported into the bin/cli.dart file.pubspec.yaml
Contains application metadata, including package information on which the application depends and required versions, just like the Flutter project
-
Run the application
$ cd cli $ dart run Hello world: 42! Copy the code
Now that we have a CLI application, let’s implement the proxy server.
Proxy server
Since the web page is now accessed through localhost, we need to create a local server to forward the request.
We set up a proxy server with port 4500.
First we need to introduce shelf_Proxy in pubspec.yaml:
shelf_proxy: ^ 0.1.0 from + 7
Copy the code
Dart is then implemented in bin/cli.dart:
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_proxy/shelf_proxy.dart';
void main(List<String> arguments) async {
var reqHandle = proxyHandler("https://d6579fc5-c18b-443b-a2ef-01c2b6be51d5.bspapp.com");
/// Bind local port 4500 and forward to a real server
var server = await shelf_io.serve(reqHandle, 'localhost'.4500);
// Set the request policy to allow all
server.defaultResponseHeaders.add('Access-Control-Allow-Origin'.The '*');
server.defaultResponseHeaders.add('Access-Control-Allow-Credentials'.true);
print('Serving at http://${server.address.host}:${server.port}');
}
Copy the code
A simple proxy server was quickly implemented with shelf_Proxy, and it was running again
$ dart run
Serving at http://localhost:4500
Copy the code
Next, we need to modify the web-demo code in lib/config.dart:
/// The development environment
class ConfigDebug extends Config {
@override
String get baseUrl => "http://localhost:4500/http/";
}
Copy the code
In ConfigDebug, set baseUrl to the address of our local proxy server.
Dart ConfigDebug:
// Configure the project environment
if (kDebugMode) {
locator.registerSingleton<Config>(ConfigDebug());
} else {
locator.registerSingleton<Config>(ConfigProduct());
}
Copy the code
Rerun our project:
Data request successful!
conclusion
Cross-domain, which is very easy to encounter in development. The solution, by way of earlier solutions through JSONP and co-domain proxies (among others, of course), did not fundamentally solve the problem. It makes sense to implement CORS through the server.
We did not configure CORS for the online server. We directly created the local server and configured CORS to forward requests to the online server and play a role of transfer. Self-sufficiency!
Refer to the
- Cross-domain and CORS that everyone should know about
- Browser same origin policy and its circumvention method
- Get started: command-line and server apps
To join Flutter wechat group, please follow the official account OldBirds