How to resolve CORS issue and JSONP issue in Ionic2

混江龙づ霸主 提交于 2019-12-22 12:39:13

问题


I am new to IONIC-2 and want to connect my mobile app to Odoo - open source ecommerce.. this connection involves some JSONP request.. I have done the same through jQuery previously.. its working properly in phonegap app.. but while I am doing the same thing with IONIC-2 it gives me CORS and JSONP errors..

can someone help me in this..

my previous jQuery code is..

/******  index.js ******/

function json(url, params) {
   var deferred = jQuery.Deferred();

   uniq_id_counter += 1;
   var payload = {
      'jsonrpc': '2.0',
      'method': 'call',
      'params': params,
      'id': ("r" + uniq_id_counter)
   };

   rpc_jsonp(url, payload).then(function (data, textStatus, jqXHR) {
      if (data.error) {
          deferred.reject(data.error);
      }
      deferred.resolve(data.result, textStatus, jqXHR);
   });

   return deferred;
 }


function rpc_jsonp(url, payload) {

   // extracted from payload to set on the url
   var data = {
      session_id: window.localStorage.getItem("session_id"),
      id: payload.id
   };

   var ajax = {
     type: "POST",
     dataType: 'jsonp',
     jsonp: 'jsonp',
     cache: false,
     data: data,
     url: url
  };

  var payload_str = JSON.stringify(payload);
  var payload_url = jQuery.param({r: payload_str});
  if (payload_url.length < 2000) {
       //  throw new Error("Payload is too big.");
  }

  console.log(ajax);
  ajax.data.r = payload_str;
  console.log(ajax);
  return jQuery.ajax(ajax);

}
/******  index.js ******/

I am calling above custom json function Login.html file..

 /******  login.html ******/

 function login(){

   var base_url = 'MY_SERVER_URL';
   json(base_url+'web/session/authenticate', {
      'base_location': base_url,
      'db':'myDB',
      'login': 'admin',
      'password':'admin'
   }).done(function (data) {

   if(data.uid != false){
       alert(data);
   }
   else{
       alert('Invalid Username or Password.');
   }

   deferred.resolve();
 }).fail(function(data){
     alert('Invalid Username or Password.');
 });

  return deferred;
}
/******  login.html ******/

I tried followed code in IONIC 2 while creating service

/****** OdooJsonService.ts ******/
import { Injectable } from '@angular/core';
import { Http, Jsonp, JSONP_PROVIDERS, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';

@Injectable()
export class OdooJsonService {
//data: any;
uniq_id_counter: number;
payload: any;
result_rpc: any;

constructor(private http: Http, private jsonp: Jsonp) {
  this.http = http;
  //this.data = null;
}

json(url, params) {

    this.uniq_id_counter = this.uniq_id_counter + 1;

    this.payload = JSON.stringify({
        'jsonrpc': '2.0',
        'method': 'call',
        'params': params,
        'id': ("r" + this.uniq_id_counter)
    });

    return this.rpc_jsonp(url, this.payload)
                    .map(res => res.json())
                    .catch(this.handleErrorOne);
}

rpc_jsonp(url, payload) {

    let data = JSON.stringify({
        //session_id: window.localStorage.getItem("session_id"),
        id: payload.id
    });

    let ajax = JSON.stringify({
        type: 'POST',
        dataType: 'jsonp',
        jsonp: 'jsonp',
        cache: false,
        data: data,
        url: url
    });

    let headers = new Headers({ 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*',
                                'Access-Control-Allow-Methods': 'PUT, GET, POST',
                                'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'});
    let options = new RequestOptions({ headers: headers });

    return this.http.post(url, ajax, options)
        .map(res => res.json())
        .catch(this.handleErrorTwo);
}

handleErrorOne(error) {
    console.error(error);
    return Observable.throw(error.json().error || 'Server error');
}

handleErrorTwo(error) {
    console.error(error);
    return Observable.throw(error.json().error || 'Server error');
}

 }       // End of OdooJsonService
 /****** OdooJsonService.ts ******/

and I am using above service in Login.ts

/****** login.ts ******/
import { Component } from '@angular/core';
import { App, NavController, MenuController, ViewController } from 'ionic-angular';
import { TaskListPage } from '../task-list/task-list';

import { Http, Jsonp, JSONP_PROVIDERS } from '@angular/http';
import { OdooJsonService } from '../../providers/odoo-json-service/odoo-json-service';

@Component({
  templateUrl: 'build/pages/login/login.html',
  providers: [OdooJsonService, JSONP_PROVIDERS]
})
export class LoginPage {
   public data: any;

   constructor(private nav: NavController, public odooJsonService: OdooJsonService) {
     this.odooMethod();
   }

   odooMethod() {
      this.odooJsonService
            .json('MY_SERVER_URL/web/session/authenticate', {'base_location': 'MY_SERVER_URL',
                    'db':'myDB', 'login': 'admin', 'password':'admin'})
            .subscribe(odooData => {
                this.data = odooData;
                console.log(JSON.stringify(this.data));
            });
     }

}
/****** login.ts ******/

error in console : (chrome)

XMLHttpRequest cannot load https://MY_SERVER_URL/web/session/authenticate. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 500.

error in console : (firefox)

/web/session/authenticate: Function declared as capable of handling request of type 'json' but called with a request of type 'http'

I am not sure whether this is right approach.. Can anyone guide to do this in right order..

how can I achieve the same in IONIC 2??

Thanks in advance.


回答1:


You can disable same origin policy in Chrome.

  1. Create a separate chrome icon on your desktop.

  1. Rename that icon to chrome (x-domain) so you know which is which.

  1. Right click on your new icon and click properties.

  1. Change the target field to "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-agent="Android" --user-data-dir="C:/temp-chrome-eng"

  1. Click Ok.

The magic happens here:

--disable-web-security

When you open your browser it will look like this:

WARNING: ONLY USE FOR TESTING PURPOSES AS THIS BROWSER HAS SECURITY DISABLED.




回答2:


The error you're receiving is because your browser is blocking the cross-origin AJAX requests (the domain doesn't respond with the required headers). However if you execute the application on a mobile device, it should work, because the application will execute the request directly. You can read more here. Does it work if you launch the app on a mobile device?




回答3:


I am running on browser using CORS extensions and plugins on both chrome and mozilla. still there is no success.

I'm not getting whether my code is wrong or something else that matters.

EDIT: Follow below two comments to disable web security of chrome on MAC machine.




回答4:


i had problem to use ionic and iis on same url ( localhost:8100 ) this chrome extension help me to solve cors issue: [enter link description here]

https://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc

also for web api you can put this peace of code inside system.webServer tag in your web.config file

<system.webServer> 
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, 
DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
...
</system.webServer>

make sure your header is correct:

let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Access-Control-Allow-Origin','*');
headers.append('Access-Control-Allow-Methods','GET,PUT,POST,DELETE');
headers.append('Access-Control-Allow-Headers','Content-Type');


来源:https://stackoverflow.com/questions/38502609/how-to-resolve-cors-issue-and-jsonp-issue-in-ionic2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!