I'm using package:dio in a Flutter web application.
Whenever I send a POST request, however, it gets changed into an OPTIONS request. The function that makes the API request looks like this:
Future<LoginResponse> login(LoginRequest request) async {
final dio = Dio(BaseOptions(baseUrl: "http://localhost:8000"));
final response = await dio.post("/login", data: request.toJson());
return LoginResponse.fromJson(jsonDecode(response.data));
}
This code sends an OPTIONS request to http://localhost:8000/login. If I add that endpoint to my server, it works.
If I send the POST request from postman manually it also works.
If I change this code to other methods (e.g. dio.delete(...)) it also maps to an OPTIONS request.
Why is dio rewriting my requests?
Related
i wanna work with this api in my flutter app
https://dev.chargily.com/docs/epay-api/
i have done the first part 1.Make Payment
but the second part 2. Payment confirmation i don't know how to do it because it contain webhook
(i wanna get the response sent via webhook_url)
this is the first part 1. Make Payment
final response = await dio
.post(
'http://epay.chargily.com.dz/api/invoice',
options: Options(headers: {
'X-Authorization':
'["API-KEY"]',
'Accept': 'application/json',
}),
data: jsonEncode(params),
)
.then((value) async {
log(value.data['checkout_url']);
var url = await value.data['checkout_url'];
work perfectly
i need the second part 2. Payment confirmation
Webhooks are a fancy word to describe a server calling another server's Web Api Endpoint. so, it's not meant to be used in the frontend.
you can't verify / get payment confirmation directly from a flutter app, you have to host your own backend / serverless function to act as a webhook and report back to the frontend environment.
So im currently trying to send images from file picker to an api that had a file input, here is the postman display and the thing was, i've tried it with numerous way that was in other post, but none of them is working for me, this is the error that i get from my web browser console and this is the code that i've tried to work with:
var postUri = Uri.parse(constanta.getMyid());
http.MultipartRequest request = new http.MultipartRequest("POST", postUri);
http.MultipartFile multipartFile = await http.MultipartFile.fromBytes(
'data', image);
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
print(response.statusCode);
i don't think the main problem was the CORS, because the api log is indicating that the request is received, but no file was attached to that request.
additional note : i've tried everything from the client side, and i cannot open/edit the backend, because it's a third party api (not owned by me).
As I can see your errors main problem here first is data was rejected from your Server as the server not allowing you to upload files and throw Cross-Origin Access which you have to solve first and then you should try.
If your postman is able to upload images on server that is because postmen itself capable of solving Cross-Origin Acess Error, so here is the solution for the node.js
If your backend is in node js you can inject the below code into your middleware.
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'XMLHttpRequest,Origin,X-Requested-With,Content-Type,Accept,Authorization');
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'PUT,POST,PATCH,DELETE,GET');
return res.status(200).json({});
}
next();
});
Or you can use localhost as a backend server.
I have spent some hours trying to figure out my problem without any success.
before reading the explanation
My nuxt site generates dynamic content and works well on client side but for SEO to work and social media shares render dynamic content i need to move my app to SSR. This axios post request do work on client side rendering but does not on SSR and I don't understand the reason and I need help to understand it.
Thanks
For starters I am building a Nuxt app that consumes Drupal as a CMS using a fully decoupled approach and I have been using it for several VUE apps without problem and now I need to do them on Nuxt with a SSR approach because I need heavy SEO on the sites. With Nuxt the same request against oauth/token on drupal doesn't work and I have gone from the complex structure we had to the simple one using both Axios and Nuxt/Axios without any success and alway getting a 400 error code.
I need to run this code first on my app so I can get drupal access token and do some request for data.
Code on store
export const actions = {
async nuxtServerInit({dispatch}, vuexContext, context, app){
await dispatch("setToken");
},
async setToken({ commit, dispatch, getters }, context) {
//prep form data to send
const FormData = require('form-data');
const body = new FormData();
body.append("param1", apiConfig.getValue("param1"));
body.append("param2", apiConfig.getValue("param2"));
body.append("param3", apiConfig.getValue("param3"));
body.append("param4", apiConfig.getValue("param4"));
body.append("param5", apiConfig.getValue("5"));
await this.$axios.$post(url, body)
.then(({data}) => {
//code to process data
commit("SET_TOKEN_DATA", data);
}).catch(error => {
console.log(error)
}).finally(() => {
console.log("FINALY");
});;
}
Some updates
base url is defined on nuxt.config as
// module options for axios
axios: {
baseURL: 'mysite.com'
},
I have tied on http request the following request using both axios and nuxt/axios, I will write short request just to show what I edid
await this.$axios.$post('mysite.com/oauth/token', body)
await this.$axios.$post('/oauth/token', body)
await this.$axios.$post('oauth/token', body)
I have also tried to use
const api = $axios.crate({
baseURL: 'url'
})
api.$axios.post('oauth/token', body)
another updated
Crated a Client Side Nuxt app and the request works.
Fix it, after literally 16 hours trying. When multiform post data you need to send FormData headers on the post and again, this works without any issues using CSR on VUE and Nuxt.
await this.$axios.$post(url, body, { headers: body.getHeaders()}).yada
I don't know if it's Axios or Nuxt the one doing this but I followed a breadcrumb trail to this post https://github.com/axios/axios/issues/318
I wanted to read through the HTML of a website from a dio get request in my flutter code. The website takes in an input, for my case in the URL and loads for some time before showing all the received data from the backend. Because it takes time to parse my request and fetch and display, my dio request only shows me half of the website, and the other half is not displayed because it is not yet fetched. I need help for making it wait or on how I can get the other half.
Here is my code:
BaseOptions options = new BaseOptions(
connectTimeout: 10000,
receiveTimeout: 10000,
);
Dio dio = new Dio(options);
String url = 'https://x.com/?url=https://x.x.x/x/';
try {
final response = await dio.get(url);
print(response.data);
final document = parse(response.data);
final downloadPage = document.getElementsByClassName('results-list');
for (Element resultsAll in downloadPage) {
final downloadLinks =
resultsAll.getElementsByClassName('download-link');
print(resultsAll.classes.toString());
}
} catch (e) {
print(e);
}
I think the problem is not with your code, but with the site you are trying to load. The package you are using is waiting for the server to return an HTTP response code (200 on success, in most cases) and then it is closing the future and returning the response from the server.
I guess what's happening in your case is that the page you are trying to load is using JavaScript to load additional content after the initial page is loaded. Similar to how Facebook, Instagram and the others have an infinite feed to scroll through.
To counter this you would will not be able to use a request-based package to pull the data, but something more in-line with a Web View package. Such a package would load the site as if it was loaded in a browser, and you would then be able to read the data from the view.
You can have a look here, for an example: https://medium.com/#janithsg/flutter-extract-web-page-html-content-from-webview-1c39e43e675d
The Flutter Web application send a HTTP REST API POST request and gets back a JSON response and a cookie in the Set-Cookie header as follows.
(Flutter (Channel beta, 1.22.0, on Microsoft Windows)
When the cookie is extracted, the response does not seem find the header value. The call and extraction code is:
var response = await http.post(url, headers: {"Content-Type": "application/json"}, body: jsonEncode(data));
if (response.statusCode == 200) {
var cookie = response.headers['set-cookie'];
print('cookie: $cookie');
}
The console result is:
cookie: null
The server side runs on ASPNet.Core 3.1 in a Docker container, however it should not be an issue, since the cookie is there in the header. So, how can I extract it in Flutter Web?
Actually my final goal is to send the cookie back with every other request. But it does not seem to happen automatically in the browser. So it is also a good solution if someone could point out the proper way of handling this scenario.
Any help is appretiated. Thanks.
The question was asked a month ago but my answer might be helpful for someone else.
Cookies in Flutter Web are managed by browser - they are automatically added to requests (to Cookie header), if the cookie was set by Set-Cookie previously - more precisely, it works correctly when you do release build.
In my case it didn't work during dev builds. My solution:
On server set headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:61656
// port number may be different
In flutter:
class member:
final http.Client _client = http.Client();
// example
Future<String> getTestString() async {
if (_client is BrowserClient)
(_client as BrowserClient).withCredentials = true;
await _client.get('https://localhost/api/login');
await _client.get('https://localhost/api/login');
return 'blah';
}
http.Client() creates an IOClient if dart:io is available and a BrowserClient if
dart:html is available - in Flutter Web dart:html is available.
Setting withCredentials to true makes cookies work.
Run your app:
flutter run -d chrome --web-port=61656
// the same port number that on server
Remember that in Flutter Web network requests are made with browser XMLHttpRequest.