我使用Google API
创建了一个应用,我正在使用Google fusion tables
作为后端,所以我也启用了fusion table API
。我正在使用ionic 2
制作混合应用。 GET
非常适合阅读表格而POST
给出了一个
error 401
function submitAnswer(button) {
var accessToken = document.getElementById("accessToken").value;
var query = "https://www.googleapis.com/fusiontables/v2/query?sql=INSERT INTO " + answerTableId + "(Answers,QuestionId,UserID) VALUES ('" + button.value + "','" + currentQueNo + "','" + userId + "')"+key+"&access_token="+accessToken;
var xhttp2 = new XMLHttpRequest();
xhttp2.onreadystatechange = function() {
//alert(this.readyState + " " + this.status);
if(this.readyState == 4) {
alert(this.responseText);
}
};
xhttp2.open("POST", query, true);
xhttp2.setRequestHeader('Authorization',accessToken);
xhttp2.send();
}
答案 0 :(得分:0)
也许你只是忘记了#34; Bearer"在您的授权值中:
xhr.setRequestHeader('Authorization', 'Bearer ' + oauthToken.access_token);
或许您在查询中对您的accessToken进行了严格编码(您需要使用encodeURIComponent(accessToken))
如果从浏览器调用此调用而不是从NodeJS调用,则可能会被CORS问题阻止。
此外,与您的问题无关:创建请求的方式对SQL注入非常敏感。一些随机用户可以在不知道任何密码的情况下删除整个数据库。
答案 1 :(得分:0)
Sincw你正在使用离子2,而不是创建像一个延伸主角http
的拦截器,就像下面的代码示例应该为你做每一个技巧,我建议你坚持它。因为它是离子2角2 +
首先,创建一个类来扩展 http 类,如api-handler.ts
:
import { Storage } from '@ionic/storage';
import { environment } from './environment';
import { Injectable } from '@angular/core';
import { Headers, Http, ConnectionBackend, RequestOptions, RequestMethod, RequestOptionsArgs } from '@angular/http';
import 'rxjs/add/operator/map';
import { Observable } from "rxjs/Observable";
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/finally';
import 'rxjs/add/observable/throw';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/operator/mergeMap';
/*
Generated class for the ApiHandler provider.
this is used to make communication with our endpoint where we pass endpoint
header information and any form of manipulation
*/
@Injectable()
export class ApiHandler extends Http {
private bearer: string = 'Plutus';
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _storage: Storage) {
super(backend, defaultOptions);
}
/**
* This is used to call our api service by inputing the service url
* @param service_url
* @param method
* @param params
* @param options
*
* @return Observable<any>
*/
callService(service_url: string, method: RequestMethod, params?: any, options?: RequestOptionsArgs): Observable<any> {
if (params == null) {
params = {};
}
options = this.requestOptions(method, params, options);
let token_promise: Promise<any> = this._storage.get('token');
return Observable.fromPromise(token_promise)
.mergeMap(token => {
console.log("token from storage", token);
if (options.headers == null && token != null) {
options.headers = new Headers({
'Authorization': `${this.bearer} ${token}`
});
}
return super.request(this.getFullUrl(service_url), options)
.catch(this.onCatch);
});
}
/**
* Request options is used to manipulate and handle needed information before
* it is sent to server
* @param options
* @returns {RequestOptionsArgs}
*/
private requestOptions(method: RequestMethod, params: any, options?: RequestOptionsArgs): RequestOptionsArgs {
if (options == null) {
options = new RequestOptions();
}
options.method = method;
if (options.method === RequestMethod.Post || options.method === RequestMethod.Put) {
options.body = params;
} else {
options.params = params;
}
return options;
}
/**
* Build API url.
* and we remove any leading / from the service calls since
* we are not needing then in making request calls
* e.g localhost:1337//base... to localhost:1337/base..
* @param url
* @returns {string}
*/
private getFullUrl(url: string): string {
if (url.charAt(0) == "/") {
url = url.substring(1);
}
return environment.endpoint + url;
}
/**
* Error handler.
* @param error
* @param caught
* @returns {ErrorObservable}
*/
private onCatch(error: any, caught: Observable<any>): Observable<any> {
return Observable.throw(x);
}
}
如果你观察我在上面代码中添加标题信息的方式,并使用允许任何形式的http方法的请求方法,如Request.Get,Request.Post,Request.Put,Request.Delete等。
其次,在您的 app.module.ts 中,通过将以下内容添加到您的提供商,将该类作为默认的http调用进行任何后端通信:[]
{
provide: ApiHandler,
useFactory: (backend: XHRBackend, defaultOptions: RequestOptions, _storage: Storage) => new ApiHandler(backend, defaultOptions, _storage),
deps: [XHRBackend, RequestOptions, Storage]
}
然后最后,在你的情况下使用它只需将它添加到你的构造函数,然后像这样直接使用
import { IFeedBack } from './../interfaces/ifeedback';
import { Observable } from 'rxjs/Observable';
import { ApiHandler } from './../util/api-handler';
import { Injectable } from '@angular/core';
import { RequestMethod } from '@angular/http';
import 'rxjs/add/operator/map';
/*
Generated class for the FeedBackServiceProvider provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
@Injectable()
export class FeedBackService {
constructor(private _apiHandler: ApiHandler) {
}
/**
* this is used to create new feedback
* @param feedback
*/
create(feedback: IFeedBack): Observable<IFeedBack> {
return this._apiHandler.callService('/feedback', RequestMethod.Post, feedback)
.map(res => <IFeedBack>res.json());
}
}
然后你可以使用新的param调用create来发送然后订阅它。
认为这应该会为你提供更好的服务。