I have an Ionic 3 app. I recently added the iOS platform.
When i run it on iOS (emulator and device) all the server requests that has headers fail with the error "Response with status: 0 for URL: null". On Android those requests works fine.
If I do the requests without headers i get the expected response from server.
I know the problem is with WKWebView and CORS. The server has the CORS configured correctly. I do the requests with #angular/http module.
Let's see some code.
This is my provider for doing requests to server:
import { Injectable } from '#angular/core';
import { Content } from 'ionic-angular';
import { Http, Headers, RequestOptions, URLSearchParams } from '#angular/http';
import { HTTP } from '#ionic-native/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Globalization } from '#ionic-native/globalization';
import { Globals } from '../providers/globals';
...
/// Here we have one example Request (it's inside a method)
/// Here I create the URL for the request
let url = this.server_url + this.server_functions.doSearch;
/// Now I create the Headers for the Request
let headers = new Headers();
/// As You can see, I have tried to pass diferent headers to server
// headers.append("Access-Control-Allow-Origin","*");
// headers.append("Origin", "https://localhost:8080");
// headers.append("Access-Control-Allow-Methods","POST, GET, OPTIONS, PUT");
// headers.append("Accept","application/json");
// headers.append("Content-Type","application/json; charset=utf-8");
/// If the user is logged in I have to send this headers to server
if ( !this.globals.guestMode ) {
headers.append("TokenAuth", this.globals.getLogRegData()["TokenAuth"]);
headers.append("IdAuth", this.globals.getLogRegData()["IdAuth"]);
}
/// And here we start the GET Request
this.http.get( url, { headers: headers } ).map(res => res.json()).subscribe(
data => {
// console.log( JSON.stringify(data) );
callback( data );
},
err => {
console.log("ELOL: "+err);
}
);
By the other way, I decided to try the #ionic-native/http module (as you can see in the imports) to avoid the WKWebView and CORS problems, but when I do the request with it, I got this error:
WARN: Native: tried calling HTTP.get, but the HTTP plugin is not installed.
WARN: Install the HTTP plugin: 'ionic cordova plugin add cordova-plugin-advanced-http'
This is how I do the Request with the native plugin:
this.httpnative.get(url, {}, {})
.then(data => {
console.log(data.status);
console.log(data.data); // data received by server
console.log(data.headers);
})
.catch(error => {
console.log(error.status);
console.log(error.error); // error message as string
console.log(error.headers);
});
This is a fragment of my app.module.ts:
import { HttpModule } from '#angular/http';
import { HTTP } from '#ionic-native/http';
...
#NgModule({
...
imports: [
...
HttpModule,
HTTP,
...
],
})
I hope some one can bring me some light on this, because I'm so lost in the paths of Ionic.
Thank You.
To avoid CORS problem specially in iOS you must use #ionic-native/http plugin which is actually Advanced HTTP plugin for API calling.
Follow below steps to use this plugin
Step 1: Add Http native plugin
$ ionic cordova plugin add cordova-plugin-advanced-http
$ npm install --save #ionic-native/http
Installation Link : HTTP
Step 2: Import HTTP native plugin in your file where you wants to cal API.
import { HTTP, HTTPResponse } from '#ionic-native/http';
Step 3: How to use this plugin for API call ?
constructor(public httpPlugin: HTTP) {
}
//Set header like this
this.httpPlugin.setHeader("content-type", "application/json");
//Call API
this.httpPlugin.get(this.url, {}, {}).then((response) => {
//Got your server response
}).catch(error => {
//Got error
});
Hope this will help you.
I have same issue in android, rest api not working in android emulator or device and give error: Response with 0 for Url: null.
and finally i got solution that there is cordova platform android version issue, if there is cordova Android version is 6.3 then it’s working properly but it there is cordova Android version is 7.0 or 7.1.1 then it’s not working for me.
So, I think in ios you should check your ios platform version and then try again.
You can check ios or android version using cli command.
ionic info
Also check your all cordova plugins is installed or not. If someone is missing then install it manually and check again.
You can check your cordova plugins using cli command.
cordova plugin -ls
I think it is helpful you.
Thanks
Related
So i'm posting a formdata object with axios to a node.js server. On iOS everything works perfectly, the data get posted and the image uploaded. But on android i'm getting this error
[AxiosError: Network Error]
here's my axios call
const handleSubmit = async (listing, { resetForm }) => {
const data = new FormData();
listing.images.forEach((image, index) =>
data.append("images", {
name: `product${Math.floor(Math.random() * 1000)}.`,
uri: image,
})
);
const res = await axios
.post("http://192.168.43.8:5000/products/addProduct", data, {
headers: {
"Content-Type": "multipart/form-data",
},
//tried adding this but didn't work out
transformRequest: (data) => data,
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
// handle error
});
}
}
Please note that on iOS it works without a problem.
here's a screenshot of the error when i used the react native debugger
if you use android emulator you need to change your ip to 10.0.2.2
change this:
http://192.168.43.8:5000/products/addProduct
to this:
http://10.0.2.2:5000/products/addProduct
By default http calls are blocked from android 9 version onwards, you either need to make your api calls HTTPS or you need to explicitly allow connection to this IP in your manifest file. Please refer this SO thread. How to allow all Network connection types HTTP and HTTPS in Android (9) Pie?
For me i am getting axios error for my emulator and did not getting any error for ios simulator. The problem with my emulator is that it is not able to connect to Internet.
So I added google DNS server 8.8.8.8 (you can add any DNS server) for my mac and it worked.
I need to implement WebSocket synchronization in our Rail project. MetaApi project's use Socket.Io as default support. Only found 2 projects (websocket-client-simple) and outdated with native socket.io. We try to implement this with Faye-Websocket and socketcluster-client-ruby but without success.
Code Example
import ioClient from 'socket.io-client';
const socket = ioClient('https://mt-client-api-v1.agiliumtrade.agiliumtrade.ai', {
path: '/ws',
reconnection: false,
query: {
'auth-token': 'token'
}
});
const request = {
accountId: '865d3a4d-3803-486d-bdf3-a85679d9fad2',
type: 'subscribe',
requestId: '57bfbc9f-108d-4131-a300-5f7d9e69c11b'
};
socket.on('connect', () => {
socket.emit('request', request);
});
socket.on('synchronization', data => {
console.log(data);
if (data.type === 'authenticated') {
console.log('authenticated event received, you can send synchronize now');
}
});
socket.on('processingError', err => {
console.error(err);
});
Socket.io protocol is a bit more complicated than a simple websocket connection, with the latter being only one of the used transports, see description in official repository. Websockets are used only after initial http handshake, so you need a somewhat full client.
I'd start with trying to consume events with a js client stub from browser, just to be sure the api is working as you expect and determine used and compatible socket.io versions (current is v4, stale ruby clients are mostly for v1). And you can peek into protocol in browser developer tools.
Once you have a successful session example and have read protocol spec above - it will be easier to craft a minimal client.
Hi I am using the hosted version of the open source parse platform (hosed version on Back4app) for my IoT project. Am using HTTP (REST) Api to communicate with the parse server and upload data. Does anyone know if it is possible to use the MQTT protocol instead of HTTP for the same with the parseplatform. I couldn't find any relevant doc for this. Apparently there's a way to install the MQTTjs on cloud code section of the platform but do not know if this really works ... Thanks in advance
Yes, it's possible, I just tested it now and it worked for me. Here are the steps that you need to follow:
1 - You only need to install this npm module as you can see at this guide.
Here is my package.json:
{
"dependencies": {
"mqtt": "2.18.8"
}
}
2 - After that, on Back4app, you need to upload the code in your cloud code and check your Server System Logs at Server Settings > Logs > Settings.
Here's a simple code that you can use to test it. I put this code in my main.js:
var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://test.mosquitto.org')
client.on('connect', function () {
client.subscribe('presence', function (err) {
if (!err) {
client.publish('presence', 'Hello mqtt')
}
})
})
client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString())
client.end()
});
I'm trying to serve a polymer application using a shelf static server. I create next structure:
polymerapp
- pubspec.yml
- bin
- server.dart
- web
- index.html
- lib
- main_app.dart
- main_app.html
Inside server.dart I put this code:
import 'dart:io' show Platform;
import 'dart:async' show runZoned;
import 'package:path/path.dart' show join, dirname;
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_static/shelf_static.dart';
void main() {
// Assumes the server lives in bin/ and that `pub build` ran
var pathToBuild = join(dirname(Platform.script.toFilePath()),
'..', 'web');
var handler = createStaticHandler(pathToBuild,
defaultDocument: 'index.html');
var portEnv = Platform.environment['PORT'];
var port = portEnv == null ? 9999 : int.parse(portEnv);
runZoned(() {
io.serve(handler, '0.0.0.0', port);
print("Serving $pathToBuild on port $port");
},
onError: (e, stackTrace) => print('Oh noes! $e $stackTrace'));
}
the rest is the template polymer application created by dart editor.
The problem is that when I try to access localhost:9999 from the browser it shows me the next errors:
Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:9999/packages/paper_elements/roboto.html
Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:9999/packages/polymertest/main_app.html
Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:9999/packages/polymer/init.dart
An error occurred loading file: package:polymer/init.dart
I want to do this for a faster way of development. In that case I don't need to build the polymer-dart application every time that I made a change.
You can pass serveFilesOutsidePath: true to createStaticHandler()
var handler = createStaticHandler(pathToBuild,
defaultDocument: 'index.html',
serveFilesOutsidePath: true);
Also, during development you can use pub serve with shelf_proxy for incremental build. See here for an example.
The combination of shelf_proxy in dev shelf_static in prod is very useful. The clever dart team came up with the idea of combining those and I borrowed the idea in mojito. You can use it as follows
import 'package:mojito/mojito.dart';
final app = mojito.init();
app.router..addStaticAssetHandler('/ui');
The code for that is here which you can copy if you prefer
I am trying to integrate grails events-push plugin to push events to browser however its not working. I made below changes for it
BuildConfig.groovy
grails.tomcat.nio = true
compile ":events-push:1.0.M7"
Config.groovy
events.push.servlet.initParams = [
'org.atmosphere.cpr.cometSupport': 'org.atmosphere.container.Tomcat7CometSupport',
"org.atmosphere.cpr.CometSupport.maxInactiveActivity": "100000"
]
tomcat.nio=true
Deleted context.xml(generated by plugin) from META-INF folder as tomcat was not working with it
In Client side i.e angular js
window.grailsEvents = new grails.Events('http://localhost:8080');
I managed to start my application successfully. I also below message in log
DEBUG cpr.DefaultBroadcaster - Broadcaster eventsbus doesn't have any associated resource. Message will be cached in the configured BroadcasterCache
Bu when I open my application in browser websocket do not work.
In serve end I see below meesage
2014-05-01 15:19:56,365 [http-nio-8080-exec-3] DEBUG cpr.AsynchronousProcessor - Timing out the connection for request AtmosphereRequest{ contextPath= servletPath=/g-eventsbus pathInfo=/eventsbus requestURI=/g-eventsbus/eventsbus requestURL=http://localhost:8080/g-eventsbus/eventsbus destroyable=false}
2014-05-01 15:19:56,366 [http-nio-8080-exec-3] WARN websocket.DefaultWebSocketProcessor - Unable to retrieve AtmosphereResource for org.apache.catalina.websocket.WsOutbound#269dd750
2014-05-01 15:19:57,783 [http-nio-8080-exec-5] DEBUG cpr.AsynchronousProcessor - Timing out the connection for request AtmosphereRequest{ contextPath= servletPath=/g-eventsbus pathInfo=/eventsbus requestURI=/g-eventsbus/eventsbus requestURL=http://localhost:8080/g-eventsbus/eventsbus destroyable=false}
I browser console end I see
WebSocket connection to 'ws://localhost:8080/g-eventsbus/eventsbus?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=1.1.0.beta3&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true&X-Cache-Date=0&topics=eventsbus' failed: WebSocket is closed before the connection is established.
Guys please help me I am struggling with this plugin from long time.
I'm using grails-events-push and almost everything works well.
In BuildConfig:
grails.servlet.version = "3.0"
grails.tomcat.nio=true
...
dependencies {
...
compile 'org.grails.plugins:events:1.0.0.BUILD-SNAPSHOT'
compile 'org.atmosphere:atmosphere-runtime:2.1.4'
}
plugins {
...
build ":tomcat:7.0.52.1"
runtime ":events-push:1.0.0.BUILD-SNAPSHOT"
}
You have to create one file to declare your events: mine is EasyRestaurantEvents.groovy
import static reactor.event.selector.Selectors.*
includes = ['push']
doWithReactor = {
reactor('grailsReactor'){
ext 'browser', [
(R('oneMessage-([0-9]+)')) : true
]
}
reactor('browser'){
ext 'browser', [
'oneMessageFromBrowser' : true
]
}
}
In the controller or service I can send an event in this way:
event('oneMessage-' + someId, mapObject)
In the client app I can receive this message in this way:
grailsEvents.on("oneMessage-666",
function(event){
alert("oneMessage was received for client 666");
});
In the server app, I can receive a message from the browser, in this way:
import reactor.spring.annotation.ReplyTo
import reactor.spring.annotation.Selector
class OneService {
#Selector(reactor = 'browser')
#ReplyTo
def oneMessageFromBrowser(Map data){
//do some work
}
}
To send an event from the browser yo can do:
grailsEvents.send('oneMessageFromBrowser', {message:'hello from browser'});
I hope this helps! I struggled with this plugin a lot! =(
But is very easy to use (when you make it work)
PS: I used another application created in angular to communicate with the server so I have to import the js manually:
"atmosphere.js": 2.1.5-javascript
"jquery.atmosphere.js": 2.1.5-jquery
Thanks mpccolorado for you reply. I got it working actually issue was in JS grails.Events should be created with globalTopicName.
var grailsEvents = new grails.Events(GRAILS_EVENT_URL, {globalTopicName: 'newReview'});