你如何成功发送 post 请求到 firebase 函数
How do you successfully send post request to firebase function
我一直致力于在 firebase 托管函数中实现 Stripe 处理,但似乎无法让它工作。每当我从浏览器发送请求来测试它时,我都会收到以下错误消息:
Access to XMLHttpRequest at 'https://firestore.googleapis.com/google.firestore.v1.Firestore/Write/channel?database=projects%app-name-a4da5%2Fdatabases%2F(default)&VER=8&RID=73206&CVER=22&X-HTTP-Session-Id=gsessionid&%24httpHeaders=Authorization%3ABearer%2tokent=1' from origin 'http://localhost:8100' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
zone-evergreen.js:2952 POST https://firestore.googleapis.com/google.firestore.v1.Firestore/Write/channel?database=projects%app-name-a4da5%2Fdatabases%2F(default)&VER=8&RID=7206&CVER=22&X-HTTP-Session-Id=gsessionid&%24httpHeaders=Authorization%3ABearer%token=1 net::ERR_FAILED
Unchecked runtime.lastError: The message port closed before a response was received.
我知道该函数有效,因为如果我通过 postman 向 firebase 函数发送请求,我会收到 200。此外,如果我在本地提供 firebase 并从浏览器访问我的 localhost firebase 服务器,它也成功了。但是当我从浏览器向 firebase 函数发送 post 请求时,它将不起作用。
我试过添加 application/json header 每个 post.
let header = new HttpHeaders();
header = header.append('Content-Type', 'application/json');
console.log('token', token);
this.http
.post(this.firebaseURL,
{
amount: 100,
currency: 'usd',
token
},
{
headers: header
})
.subscribe(data => {
console.log('data', data);
});
}
这里是 firebase 函数:
exports.payWithStripe = functions.https.onRequest((request, response) => {
// tslint:disable-next-line:max-line-length
console.log('exports.payWithStripe = functions.https.onRequest', request);
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
// eslint-disable-next-line promise/catch-or-return
stripe.charges.create({
amount: request.body.amount,
currency: request.body.currency,
source: request.body.token,
}).then((charge: any) => {
// asynchronously called
console.log('then after charges', charge);
response.send(charge);
})
.catch((err: any) => {
console.log('error from charges', err);
});
});
这正在用于 PWA。
同样,如果我从浏览器离子服务和测试,如果我在本地服务 firebase 并将 post 发送到本地 firebase,它会工作,但如果我尝试将 post 发送到 firebase,它会失败后端功能。
如果我通过 postman 发送请求,它在本地和 firebase 中都有效。
另一件同样有效的事情是从前端向 Stripe 请求令牌,内容如下:
this.stripe.createSource(this.cardDetails).then(result => {
if (result.error) {
const errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
console.log('results', result.source);
this.makePayment(result.source.id);
}
});
除了使用测试卡从浏览器向 firebase 函数发出后端请求外,一切正常。
我不确定我的 postman 请求与我在代码中构建的请求有何不同。我的 postman 请求只有 Content-Type = application/json
同样,如果我从浏览器发送请求并在本地提供 firebase,它可以正常工作,只是不将 post 发送到后端。
我也试过这个:
makePayment(token) {
let header = new HttpHeaders();
header = header.append('Content-Type', 'text/plain');
const body = {
amount: 100,
currency: 'usd',
token
};
const postBody = JSON.stringify(body);
console.log('token', token);
this.http
.post(this.firebaseURL,
postBody,
{
headers: header
})
.subscribe(data => {
console.log('data', data);
});
}
我已经坚持了一段时间...任何帮助都将不胜感激。
如 HTTPS Cloud Functions doc 中所述,您需要将代码封装在一个块中,例如:
return cors(req, res, () => {
// ...
});
因此,对于您的 CF,以下内容应该有效(未经测试):
// ...
const cors = require('cors')({ origin: true });
// ...
exports.payWithStripe = functions.https.onRequest((request, response) => {
console.log('exports.payWithStripe = functions.https.onRequest', request);
return cors(request, response, () => {
stripe.charges.create({
amount: request.body.amount,
currency: request.body.currency,
source: request.body.token,
}).then((charge: any) => {
// asynchronously called
console.log('then after charges', charge);
response.send(charge);
})
.catch((err: any) => {
console.log('error from charges', err);
// !!!! Here you need to send back a response, as follows !!!
response.status(500).send(err); // <= see addition here !!!
});
});
});
此外,请参阅 catch
块中的错误处理方式。
我一直致力于在 firebase 托管函数中实现 Stripe 处理,但似乎无法让它工作。每当我从浏览器发送请求来测试它时,我都会收到以下错误消息:
Access to XMLHttpRequest at 'https://firestore.googleapis.com/google.firestore.v1.Firestore/Write/channel?database=projects%app-name-a4da5%2Fdatabases%2F(default)&VER=8&RID=73206&CVER=22&X-HTTP-Session-Id=gsessionid&%24httpHeaders=Authorization%3ABearer%2tokent=1' from origin 'http://localhost:8100' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
zone-evergreen.js:2952 POST https://firestore.googleapis.com/google.firestore.v1.Firestore/Write/channel?database=projects%app-name-a4da5%2Fdatabases%2F(default)&VER=8&RID=7206&CVER=22&X-HTTP-Session-Id=gsessionid&%24httpHeaders=Authorization%3ABearer%token=1 net::ERR_FAILED
Unchecked runtime.lastError: The message port closed before a response was received.
我知道该函数有效,因为如果我通过 postman 向 firebase 函数发送请求,我会收到 200。此外,如果我在本地提供 firebase 并从浏览器访问我的 localhost firebase 服务器,它也成功了。但是当我从浏览器向 firebase 函数发送 post 请求时,它将不起作用。
我试过添加 application/json header 每个 post.
let header = new HttpHeaders();
header = header.append('Content-Type', 'application/json');
console.log('token', token);
this.http
.post(this.firebaseURL,
{
amount: 100,
currency: 'usd',
token
},
{
headers: header
})
.subscribe(data => {
console.log('data', data);
});
}
这里是 firebase 函数:
exports.payWithStripe = functions.https.onRequest((request, response) => {
// tslint:disable-next-line:max-line-length
console.log('exports.payWithStripe = functions.https.onRequest', request);
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
// eslint-disable-next-line promise/catch-or-return
stripe.charges.create({
amount: request.body.amount,
currency: request.body.currency,
source: request.body.token,
}).then((charge: any) => {
// asynchronously called
console.log('then after charges', charge);
response.send(charge);
})
.catch((err: any) => {
console.log('error from charges', err);
});
});
这正在用于 PWA。
同样,如果我从浏览器离子服务和测试,如果我在本地服务 firebase 并将 post 发送到本地 firebase,它会工作,但如果我尝试将 post 发送到 firebase,它会失败后端功能。
如果我通过 postman 发送请求,它在本地和 firebase 中都有效。
另一件同样有效的事情是从前端向 Stripe 请求令牌,内容如下:
this.stripe.createSource(this.cardDetails).then(result => {
if (result.error) {
const errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
console.log('results', result.source);
this.makePayment(result.source.id);
}
});
除了使用测试卡从浏览器向 firebase 函数发出后端请求外,一切正常。
我不确定我的 postman 请求与我在代码中构建的请求有何不同。我的 postman 请求只有 Content-Type = application/json
同样,如果我从浏览器发送请求并在本地提供 firebase,它可以正常工作,只是不将 post 发送到后端。
我也试过这个:
makePayment(token) {
let header = new HttpHeaders();
header = header.append('Content-Type', 'text/plain');
const body = {
amount: 100,
currency: 'usd',
token
};
const postBody = JSON.stringify(body);
console.log('token', token);
this.http
.post(this.firebaseURL,
postBody,
{
headers: header
})
.subscribe(data => {
console.log('data', data);
});
}
我已经坚持了一段时间...任何帮助都将不胜感激。
如 HTTPS Cloud Functions doc 中所述,您需要将代码封装在一个块中,例如:
return cors(req, res, () => {
// ...
});
因此,对于您的 CF,以下内容应该有效(未经测试):
// ...
const cors = require('cors')({ origin: true });
// ...
exports.payWithStripe = functions.https.onRequest((request, response) => {
console.log('exports.payWithStripe = functions.https.onRequest', request);
return cors(request, response, () => {
stripe.charges.create({
amount: request.body.amount,
currency: request.body.currency,
source: request.body.token,
}).then((charge: any) => {
// asynchronously called
console.log('then after charges', charge);
response.send(charge);
})
.catch((err: any) => {
console.log('error from charges', err);
// !!!! Here you need to send back a response, as follows !!!
response.status(500).send(err); // <= see addition here !!!
});
});
});
此外,请参阅 catch
块中的错误处理方式。