Getting CORS error when trying to use http post to send data to the nodejs API

im getting this when debugging,

XMLHttpRequest cannot load…
has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost’ is therefore not allowed access.
when i run the app in my android device i get this.

anyone know how to fix this? thanks.

Hi, start by looking at

I tried this but still getting the error is there a way that i can allow all the http requests from my android apk?

Hi @dimithrab, so CORS settings are something you set/configure on the server.
Do note that http://localhost is where the Ionic app is served from on Android.
Is your app working at all on the Android device?
Not 100% sure what you are trying to do but where are you trying to POST the data to?

i’ve tried using ionic native http then it worked but now i’m getting this error when im trying to post.

ERROR Error: advanced-http: “data” option is configured to support only following data types: Object

this is my code,

const formData = new FormData();

      formData.append('image', this.image);   //to add images to the image file 

      let nativeCall = this.nativehttp.post('http://***********', formData,{});

      

      from(nativeCall).subscribe((response: any) => {

      console.log(response);

      this.displayToastMessage("Image uploaded");

I guess you are using the Angular HttpClient? You should not allow localhost to Servers CORS Settings, so try this Plugin for all Http Stuff: https://ionicframework.com/docs/native/http

You can enable SLL-Pinning with it too, to have a higher security against Man in the MiddleAttack

oh just sen your answer. Sorry my bad. To send Formdata via post you need to set serializer: 'multipart'. I do it like this:

this.http.sendRequest(url, {
  method: 'post',
  serializer: 'multipart',
  data: data, // form data
})

const formData = new FormData();

      formData.append('image', this.image);   //to add images to the image file 

      this.nativehttp.setDataSerializer('multipart');

      let nativeCall = this.nativehttp.post(url, formData,{});

      

      from(nativeCall).subscribe((response: any) => {

      console.log(response);

      this.displayToastMessage("Image uploaded");

You mean like this??

I think this sets it globally. Better is:

this.http.sendRequest(url, {
  method: 'post',
  serializer: 'multipart',
  data: data, // form data
})
1 Like

Unhandled Promise rejection:
getting this error

That just means that the Promise was rejected, but you do not .catch() it

async selectImage() {

const actionSheet = await this.actionSheetController.create({

  header: "Select Image source",

  buttons: [{

    text: 'Send from Gallery',

    handler: () => {                      //for retrive images from the phone gallery

     

      const formData = new FormData();

      formData.append('image', this.image);   //to add images to the image file 

      this.nativehttp.sendRequest(url, {

        method: 'post',

        serializer: 'multipart',

        data: formData, // form data

      });

      this.displayToastMessage("Image uploaded");

    

    }

  },

this is my code i dont know why am i getting this error

Do you know anything about Promises? Read some Guides maybe, like https://medium.com/javascript-in-plain-english/a-guide-to-javascript-promises-da50eff327d7

1 Like

import { Component, OnInit, ChangeDetectorRef } from ‘@angular/core’;

import { Camera, CameraOptions, PictureSourceType } from ‘@ionic-native/camera/ngx’;

import { ActionSheetController, ToastController, Platform, LoadingController } from ‘@ionic/angular’;

import { File, FileEntry } from ‘@ionic-native/file/ngx’;

import { HttpClient } from ‘@angular/common/http’;

import { WebView } from ‘@ionic-native/ionic-webview/ngx’;

import { Storage } from ‘@ionic/storage’;

import { FilePath } from ‘@ionic-native/file-path/ngx’;

import { Network } from ‘@ionic-native/network/ngx’;

import { FileTransfer, FileUploadOptions, FileTransferObject } from ‘@ionic-native/file-transfer/ngx’;

import { finalize, retry } from ‘rxjs/operators’;

import { HTTP } from ‘@ionic-native/http/ngx’;

import { from } from ‘rxjs’;

const STORAGE_KEY = ‘my_images’;

@Component({

selector: ‘app-home’,

templateUrl: ‘home.page.html’,

styleUrls: [‘home.page.scss’],

})

export class HomePage implements OnInit {

images = ;

constructor(

private camera: Camera,

private file: File,

private webview: WebView,

private actionSheetController: ActionSheetController,

private toastController: ToastController,

private storage: Storage,

private plt: Platform,

private nativehttp: HTTP,

private loadingController: LoadingController,

private ref: ChangeDetectorRef,

private filePath: FilePath,

public network: Network,

public transfer: FileTransfer,

private http: HttpClient) {

this.network.onDisconnect().subscribe(() => {

  //to check the network status 

});

this.network.onConnect().subscribe(() => {

  setTimeout(() => {

  }, 2000);

});

}

ngOnInit() {

this.plt.ready().then(() => {

  this.loadStoredImages();

});

}

loadStoredImages() {

this.storage.get(STORAGE_KEY).then(images => {

  if (images) {

    let arr = JSON.parse(images);

    this.images = [];

    for (let img of arr) {

      let filePath = this.file.dataDirectory + img;

      let resPath = this.pathForImage(filePath);

      this.images.push({ name: img, path: resPath, filePath: filePath });

    }

  }

});

}

pathForImage(img) {

if (img === null) {

  return '';

} else {

  let converted = this.webview.convertFileSrc(img);

  return converted;

}

}

async presentToast(text) {

const toast = await this.toastController.create({

  message: text,

  position: 'bottom',

  duration: 3000

});

toast.present();

}

async selectImage() {

const actionSheet = await this.actionSheetController.create({

  header: "Select Image source",

  buttons: [{

    text: 'Load from Library',

    handler: () => {

      this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);

    }

  },

  {

    text: 'Use Camera',

    handler: () => {

      this.takePicture(this.camera.PictureSourceType.CAMERA);

    }

  },

  {

    text: 'Cancel',

    role: 'cancel'

  }

  ]

});

await actionSheet.present();

}

takePicture(sourceType: PictureSourceType) {

var options: CameraOptions = {

  quality: 100,

  sourceType: sourceType,

  saveToPhotoAlbum: false,

  correctOrientation: true

};

this.camera.getPicture(options).then(imagePath => {

  if (this.plt.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {

    this.filePath.resolveNativePath(imagePath)

      .then(filePath => {

        let correctPath = filePath.substr(0, filePath.lastIndexOf('/') + 1);

        let currentName = imagePath.substring(imagePath.lastIndexOf('/') + 1, imagePath.lastIndexOf('?'));

        this.copyFileToLocalDir(correctPath, currentName, this.createFileName());

      });

  } else {

    var currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);

    var correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);

    this.copyFileToLocalDir(correctPath, currentName, this.createFileName());

  }

});

}

createFileName() {

var d = new Date(),

  n = d.getTime(),

  newFileName = n + ".jpg";

return newFileName;

}

copyFileToLocalDir(namePath, currentName, newFileName) {

this.file.copyFile(namePath, currentName, this.file.dataDirectory, newFileName).then(success => {

  this.updateStoredImages(newFileName);

}, error => {

  this.presentToast('Error while storing file.');

});

}

updateStoredImages(name) {

this.storage.get(STORAGE_KEY).then(images => {

  let arr = JSON.parse(images);

  if (!arr) {

    let newImages = [name];

    this.storage.set(STORAGE_KEY, JSON.stringify(newImages));

  } else {

    arr.push(name);

    this.storage.set(STORAGE_KEY, JSON.stringify(arr));

  }

  let filePath = this.file.dataDirectory + name;

  let resPath = this.pathForImage(filePath);

  let newEntry = {

    name: name,

    path: resPath,

    filePath: filePath

  };

  this.images = [newEntry, ...this.images];

  this.ref.detectChanges(); // trigger change detection cycle

});

}

deleteImage(imgEntry, position) {

this.images.splice(position, 1);

this.storage.get(STORAGE_KEY).then(images => {

  let arr = JSON.parse(images);

  let filtered = arr.filter(name => name != imgEntry.name);

  this.storage.set(STORAGE_KEY, JSON.stringify(filtered));

  var correctPath = imgEntry.filePath.substr(0, imgEntry.filePath.lastIndexOf('/') + 1);

  this.file.removeFile(correctPath, imgEntry.name).then(res => {

    this.presentToast('File removed.');

  });

});

}

startUpload(imgEntry) {

this.file.resolveLocalFilesystemUrl(imgEntry.filePath)

  .then(entry => {

    (<FileEntry>entry).file(file => this.readFile(file))

  })

  .catch(err => {

    this.presentToast('Error while reading file.');

  });

}

readFile(file: any) {

const reader = new FileReader();

reader.onload = () => {

  const formData = new FormData();

  const imgBlob = new Blob([reader.result], {

    type: file.type

  });

  formData.append('image', imgBlob, file.name);

  this.uploadImageData(formData);

};

reader.readAsArrayBuffer(file);

}

async uploadImageData(formData: FormData) {

const loading = await this.loadingController.create({

  message: 'Uploading image...',

});

await loading.present();

let nativeCall = this.nativehttp.put(url, formData, {});



from(nativeCall).pipe(

  finalize(() => {

    loading.dismiss();

  })

).subscribe(res => {

  if (res['success']) {

    this.presentToast('File upload complete.');

  } else {

    this.presentToast('File upload failed.');

  }

});

}

}

no ill look into it thanks. i’m actually new to ionic and i’m in a hurry to make this code works .
can you tell me what should i change inside the async uploadImageData(formData: FormData) method?
can you put the code that i have to change ? this would be really helpful.

Http requests should also handle error responses. The subscribe method accepts success callback as the first parameter and error callback as the second.

I’m not sure what is your JSON response structure, but it usually DOESN’T have a “success” property.

Several issues might be the problem, if you want I can email you my phone number, so you can give me a call.

async uploadImageData(formData: FormData) {

const loading = await this.loadingController.create({

  message: 'Uploading image...',

});

await loading.present();

let nativeCall = this.nativehttp.put(url, formData, {});



from(nativeCall).pipe(

  finalize(() => {

    loading.dismiss();

  })

).subscribe(res => {

  if (res['success']) {

    this.presentToast('File upload complete.');

  } else {

    this.presentToast('File upload failed.');

  }

}, err => console.log(err));
}

}

Are you sending any images or media file in your request ?
I had the same problem and it turned out to be from nginx, so I added

http {
    client_max_body_size 100M;
}

in /etc/nginx/nginx.conf file
and my problem resolved

As I am using GitHub - silkimen/cordova-plugin-advanced-http: Cordova / Phonegap plugin for communicating with HTTP servers. Allows for SSL pinning! plugin for developing my Android project to connect ODOO Framework I am suggesting this plugin for you. HTTP - Ionic Documentation Says, CORS do not apply in its operation. But it works only in native level, not in browser. A emulator or a real device is required for simulation.