如何解决Ionic2中的CORS问题和JSONP问题

时间:2016-07-21 11:07:00

标签: angular cors jsonp ionic2

我是IONIC-2的新手,想要将我的移动应用与Odoo - open source ecommerce相关联。 此连接涉及一些JSONP请求..我之前通过jQuery完成了相同的工作..它在phonegap app中正常工作..但我正在使用{{1它给了我IONIC-2CORS错误..

有人可以帮我这个..

我以前的JSONP代码是..

jQuery

我在/****** 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 ******/ 函数custom json文件上面调用..

Login.html

在创建 /****** 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 ******/

时,我尝试在IONIC 2中跟踪代码
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 ******/

中的service上方
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 ******/
控制台中的

错误:(firefox)

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.

我不确定这是否是正确的方法..任何人都可以指导以正确的顺序执行此操作。

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

中实现相同目标

提前致谢。

4 个答案:

答案 0 :(得分:5)

您可以在Chrome中停用相同的来源政策。

  1. 在桌面上创建单独的Chrome图标。
  2. Dual Chrome

    1. 将该图标重命名为chrome(x-domain),以便知道哪个是。
    2. Chrome rename

      1. 右键单击新图标,然后单击属性。
      2. Properties

        1. 将目标字段更改为"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-agent="Android" --user-data-dir="C:/temp-chrome-eng"
        2. Target Field

          1. 点击确定。
          2. 魔术发生在这里:

            --disable-web-security
            

            当您打开浏览器时,它将如下所示:

            Finished

            警告:仅在此浏览器已禁用安全时才用于测试目的。

答案 1 :(得分:0)

您收到的错误是因为您的浏览器阻止了跨源AJAX请求(域没有响应所需的标头)。但是,如果您在移动设备上执行该应用程序,它应该可以工作,因为应用程序将直接执行请求。您可以阅读更多here。如果您在移动设备上启动应用程序,它是否有效?

答案 2 :(得分:0)

我在CORS extensionsplugins上使用chromemozilla在浏览器上运行。仍然没有成功。

我不知道我的代码是错还是其他重要事项。

编辑:请按照以下两条评论来停用MAC机上的Chrome网络安全。

答案 3 :(得分:0)

我有问题在同一个网址上使用离子和iis(localhost:8100) 这个chrome扩展帮助我解决了cors问题:[在这里输入链接描述]

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

对于web api,您可以将这段代码放在web.config文件中的system.webServer标记内

<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>

确保标题正确无误:

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');