如何解决 Ionic2 中的 CORS 问题和 JSONP 问题
How to resolve CORS issue and JSONP issue in Ionic2
我是 IONIC-2
的新手,想将我的移动应用程序连接到 Odoo - open source ecommerce
..
此连接涉及一些 JSONP
请求。我之前通过 jQuery
做过同样的事情..它在 phonegap
应用程序中正常工作..但是当我对 [=16 做同样的事情时=] 它给了我 CORS
和 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
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 ******/
我在创建 service
时尝试遵循 IONIC 2
中的代码
/****** 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 ******/
我在 Login.ts
中使用上面的 service
/****** 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 ******/
控制台错误:
(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.
控制台错误:(firefox)
/web/session/authenticate: Function declared as capable of handling request of type 'json' but called with a request of type 'http'
我不确定这是否是正确的方法..任何人都可以指导以正确的顺序执行此操作..
如何在 IONIC 2
中实现同样的效果??
提前致谢。
您收到的错误是因为您的浏览器阻止了 cross-origin AJAX 请求(域未响应所需的 headers)。但是,如果您在移动设备上执行应用程序,它应该可以工作,因为应用程序将直接执行请求。您可以阅读更多 here。如果您在移动设备上启动该应用程序是否有效?
您可以在 Chrome 中禁用同源策略。
- 在您的桌面上创建一个单独的 chrome 图标。
- 将该图标重命名为 chrome(x 域)以便您知道哪个是哪个。
- 右键单击您的新图标并单击属性。
- 将目标字段更改为
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-agent="Android" --user-data-dir="C:/temp-chrome-eng"
- 单击确定。
奇迹发生在这里:
--disable-web-security
当您打开浏览器时,它将如下所示:
警告:仅用于测试目的,因为此浏览器已禁用安全功能。
我 运行 在浏览器上使用 CORS extensions
和 plugins
在 chrome
和 mozilla
上。还是没有成功。
我不知道我的代码是错误的还是其他重要的事情。
编辑: 按照以下两条评论在 MAC 机器上禁用 chrome 的网络安全。
我在同一个 url ( localhost:8100 ) 上使用 ionic 和 iis 时遇到问题
这个 chrome 扩展帮助我解决了 cors 问题:[在此处输入 link 描述]
https://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc
也适用于网络 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>
确保你的header是正确的:
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');
我是 IONIC-2
的新手,想将我的移动应用程序连接到 Odoo - open source ecommerce
..
此连接涉及一些 JSONP
请求。我之前通过 jQuery
做过同样的事情..它在 phonegap
应用程序中正常工作..但是当我对 [=16 做同样的事情时=] 它给了我 CORS
和 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
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 ******/
我在创建 service
IONIC 2
中的代码
/****** 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 ******/
我在 Login.ts
service
/****** 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 ******/
控制台错误: (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.
控制台错误:(firefox)
/web/session/authenticate: Function declared as capable of handling request of type 'json' but called with a request of type 'http'
我不确定这是否是正确的方法..任何人都可以指导以正确的顺序执行此操作..
如何在 IONIC 2
中实现同样的效果??
提前致谢。
您收到的错误是因为您的浏览器阻止了 cross-origin AJAX 请求(域未响应所需的 headers)。但是,如果您在移动设备上执行应用程序,它应该可以工作,因为应用程序将直接执行请求。您可以阅读更多 here。如果您在移动设备上启动该应用程序是否有效?
您可以在 Chrome 中禁用同源策略。
- 在您的桌面上创建一个单独的 chrome 图标。
- 将该图标重命名为 chrome(x 域)以便您知道哪个是哪个。
- 右键单击您的新图标并单击属性。
- 将目标字段更改为
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-agent="Android" --user-data-dir="C:/temp-chrome-eng"
- 单击确定。
奇迹发生在这里:
--disable-web-security
当您打开浏览器时,它将如下所示:
警告:仅用于测试目的,因为此浏览器已禁用安全功能。
我 运行 在浏览器上使用 CORS extensions
和 plugins
在 chrome
和 mozilla
上。还是没有成功。
我不知道我的代码是错误的还是其他重要的事情。
编辑: 按照以下两条评论在 MAC 机器上禁用 chrome 的网络安全。
我在同一个 url ( localhost:8100 ) 上使用 ionic 和 iis 时遇到问题 这个 chrome 扩展帮助我解决了 cors 问题:[在此处输入 link 描述]
https://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc
也适用于网络 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>
确保你的header是正确的:
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');