如何处理 AMP 的 CORS
How to handle CORS for AMP
我有一个页面使用 amp-list
通过 JSON 文件动态列出产品。我的目录结构如下:*root*/amp/product-name/
,然后在 product-name
目录中,我有一个带有 AMP HTML 的 index.html
和一个包含产品的 products.json
我在页面上显示的数据。如果我直接访问页面,一切都按预期工作:
https://example.com/amp/product-name/
从ampproject.orgCDN访问时出现问题。
这是实际页面,如果您访问控制台,您会看到存在 CORS 错误。我该如何处理?文档不清楚如何准确处理,只是一个非常模糊的概述,所以对于新手来说这对我来说没有意义,我不能凭直觉知道如何去做。我知道我需要某种请求处理程序,我通过将代码从 AMP 自己的 app.js 他们 link 复制到他们的文档中来部分完成。在 amp-list
元素中,我之前将 src 直接指向 JSON 文件,但现在我看到我需要指向一个处理程序(如 JS 文件),然后设置处理程序请求 header 然后输出正确的 JSON.
这是我的请求处理程序:
/**
* @param {string} url
* @param {string} param
* @param {*} value
* @return {string}
*/
function addQueryParam(url, param, value) {
const paramValue = encodeURIComponent(param) + '=' + encodeURIComponent(value);
if (!url.includes('?')) {
url += '?' + paramValue;
} else {
url += '&' + paramValue;
}
return url;
}
function enableCors(req, res, origin, opt_exposeHeaders) {
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Origin', 'https://www-perfectimprints-com.cdn.ampproject.org');
res.setHeader('Access-Control-Expose-Headers', ['AMP-Access-Control-Allow-Source-Origin'].concat(opt_exposeHeaders || []).join(', '));
if (req.query.__amp_source_origin) {
res.setHeader('AMP-Access-Control-Allow-Source-Origin', req.query.__amp_source_origin);
}
}
function assertCors(req, res, opt_validMethods, opt_exposeHeaders, opt_ignoreMissingSourceOrigin) {
// Allow disable CORS check (iframe fixtures have origin 'about:srcdoc').
if (req.query.cors == '0') {
return;
}
const validMethods = opt_validMethods || ['GET', 'POST', 'OPTIONS'];
const invalidMethod = req.method + ' method is not allowed. Use POST.';
const invalidOrigin = 'Origin header is invalid.';
const invalidSourceOrigin = '__amp_source_origin parameter is invalid.';
const unauthorized = 'Unauthorized Request';
let origin;
if (validMethods.indexOf(req.method) == -1) {
res.statusCode = 405;
res.end(JSON.stringify({
message: invalidMethod
}));
throw invalidMethod;
}
if (req.headers.origin) {
origin = req.headers.origin;
if (!ORIGIN_REGEX.test(req.headers.origin)) {
res.statusCode = 500;
res.end(JSON.stringify({
message: invalidOrigin
}));
throw invalidOrigin;
}
if (!opt_ignoreMissingSourceOrigin && !SOURCE_ORIGIN_REGEX.test(req.query.__amp_source_origin)) {
res.statusCode = 500;
res.end(JSON.stringify({
message: invalidSourceOrigin
}));
throw invalidSourceOrigin;
}
} else if (req.headers['amp-same-origin'] == 'true') {
origin = getUrlPrefix(req);
} else {
res.statusCode = 401;
res.end(JSON.stringify({
message: unauthorized
}));
throw unauthorized;
}
enableCors(req, res, origin, opt_exposeHeaders);
}
这就是我在 HTML 中使用的内容。
<amp-list credentials="include" width="auto" height="1500" layout="fixed-height" src="https://perfectimprints.com/amp/handle-amp-requests.js" class="m1">
<template type="amp-mustache" id="amp-template-id">
<div class="product" style="padding-top: 1em;">
<a class="wrapper-link" href="{{ link }}">
<amp-img alt="{{ title }}" width="1000" height="1000" src="{{ src }}" layout="responsive"></amp-img>
<h3 class="product-name text-centered">
{{title}}
</h3>
<h4 class="text-centered sku margin-minus-1">{{ sku }}</h4>
<div class="text-centered get-price">
<a class="text-centered get-price-link" href="{{ link }}">Get pricing now</a>
</div>
</a>
</div>
</template>
<div overflow role="button" aria-label="Show more">
Show more
</div>
</amp-list>
假设您使用的是 Apache 服务器,您可以在 htaccess 文件中像这样设置 CORS header:
Header set Access-Control-Allow-Origin "https://www-perfectimprints-com.cdn.ampproject.org"
Header set Access-Control-Allow-Origin "https://www-perfectimprints-com.amp.cloudflare.com"
然后确保您的 htaccess 文件已上传到包含您的网站的目录 HTML。在我管理的网站上,这就是 set-up 的方式,一切都对我们有效。
这是对我有用的解决方案。
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Origin "https://example-com.cdn.ampproject.org"
Header set Access-Control-Allow-Source-Origin "https://example.com"
Header set Access-Control-Expose-Headers AMP-Access-Control-Allow-Source-Origin
Header set AMP-Access-Control-Allow-Source-Origin "https://example.com"
感谢@Craig Scott 提示帮我解决
可怜的、没有经验的处理 AMP 页面的人有祸了。
对于使用 nodejs 的人,语法如下:
res.set('AMP-Redirect-To', encodedUrl);
res.set('Access-Control-Allow-Origin', websiteHostname);
res.set('AMP-Access-Control-Allow-Source-Origin', websiteHostname);
res.set('Access-Control-Expose-Headers', [
'AMP-Access-Control-Allow-Source-Origin',
'AMP-Redirect-To',
]);
res.set('Access-Control-Allow-Credentials', 'true');
ِ另一个解决方案是使用 amp-toolbox-cors
库并将其 verifyOrigin
选项设置为 false
。
import ampCors from 'amp-toolbox-cors';
app.use(
ampCors({
verifyOrigin: false,
}),
);
注意所有来源都是这样的。实际上你应该只允许两个。
希望以后能节省一些人的时间!
我有一个页面使用 amp-list
通过 JSON 文件动态列出产品。我的目录结构如下:*root*/amp/product-name/
,然后在 product-name
目录中,我有一个带有 AMP HTML 的 index.html
和一个包含产品的 products.json
我在页面上显示的数据。如果我直接访问页面,一切都按预期工作:
https://example.com/amp/product-name/
从ampproject.orgCDN访问时出现问题。
这是实际页面,如果您访问控制台,您会看到存在 CORS 错误。我该如何处理?文档不清楚如何准确处理,只是一个非常模糊的概述,所以对于新手来说这对我来说没有意义,我不能凭直觉知道如何去做。我知道我需要某种请求处理程序,我通过将代码从 AMP 自己的 app.js 他们 link 复制到他们的文档中来部分完成。在 amp-list
元素中,我之前将 src 直接指向 JSON 文件,但现在我看到我需要指向一个处理程序(如 JS 文件),然后设置处理程序请求 header 然后输出正确的 JSON.
这是我的请求处理程序:
/**
* @param {string} url
* @param {string} param
* @param {*} value
* @return {string}
*/
function addQueryParam(url, param, value) {
const paramValue = encodeURIComponent(param) + '=' + encodeURIComponent(value);
if (!url.includes('?')) {
url += '?' + paramValue;
} else {
url += '&' + paramValue;
}
return url;
}
function enableCors(req, res, origin, opt_exposeHeaders) {
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Origin', 'https://www-perfectimprints-com.cdn.ampproject.org');
res.setHeader('Access-Control-Expose-Headers', ['AMP-Access-Control-Allow-Source-Origin'].concat(opt_exposeHeaders || []).join(', '));
if (req.query.__amp_source_origin) {
res.setHeader('AMP-Access-Control-Allow-Source-Origin', req.query.__amp_source_origin);
}
}
function assertCors(req, res, opt_validMethods, opt_exposeHeaders, opt_ignoreMissingSourceOrigin) {
// Allow disable CORS check (iframe fixtures have origin 'about:srcdoc').
if (req.query.cors == '0') {
return;
}
const validMethods = opt_validMethods || ['GET', 'POST', 'OPTIONS'];
const invalidMethod = req.method + ' method is not allowed. Use POST.';
const invalidOrigin = 'Origin header is invalid.';
const invalidSourceOrigin = '__amp_source_origin parameter is invalid.';
const unauthorized = 'Unauthorized Request';
let origin;
if (validMethods.indexOf(req.method) == -1) {
res.statusCode = 405;
res.end(JSON.stringify({
message: invalidMethod
}));
throw invalidMethod;
}
if (req.headers.origin) {
origin = req.headers.origin;
if (!ORIGIN_REGEX.test(req.headers.origin)) {
res.statusCode = 500;
res.end(JSON.stringify({
message: invalidOrigin
}));
throw invalidOrigin;
}
if (!opt_ignoreMissingSourceOrigin && !SOURCE_ORIGIN_REGEX.test(req.query.__amp_source_origin)) {
res.statusCode = 500;
res.end(JSON.stringify({
message: invalidSourceOrigin
}));
throw invalidSourceOrigin;
}
} else if (req.headers['amp-same-origin'] == 'true') {
origin = getUrlPrefix(req);
} else {
res.statusCode = 401;
res.end(JSON.stringify({
message: unauthorized
}));
throw unauthorized;
}
enableCors(req, res, origin, opt_exposeHeaders);
}
这就是我在 HTML 中使用的内容。
<amp-list credentials="include" width="auto" height="1500" layout="fixed-height" src="https://perfectimprints.com/amp/handle-amp-requests.js" class="m1">
<template type="amp-mustache" id="amp-template-id">
<div class="product" style="padding-top: 1em;">
<a class="wrapper-link" href="{{ link }}">
<amp-img alt="{{ title }}" width="1000" height="1000" src="{{ src }}" layout="responsive"></amp-img>
<h3 class="product-name text-centered">
{{title}}
</h3>
<h4 class="text-centered sku margin-minus-1">{{ sku }}</h4>
<div class="text-centered get-price">
<a class="text-centered get-price-link" href="{{ link }}">Get pricing now</a>
</div>
</a>
</div>
</template>
<div overflow role="button" aria-label="Show more">
Show more
</div>
</amp-list>
假设您使用的是 Apache 服务器,您可以在 htaccess 文件中像这样设置 CORS header:
Header set Access-Control-Allow-Origin "https://www-perfectimprints-com.cdn.ampproject.org"
Header set Access-Control-Allow-Origin "https://www-perfectimprints-com.amp.cloudflare.com"
然后确保您的 htaccess 文件已上传到包含您的网站的目录 HTML。在我管理的网站上,这就是 set-up 的方式,一切都对我们有效。
这是对我有用的解决方案。
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Origin "https://example-com.cdn.ampproject.org"
Header set Access-Control-Allow-Source-Origin "https://example.com"
Header set Access-Control-Expose-Headers AMP-Access-Control-Allow-Source-Origin
Header set AMP-Access-Control-Allow-Source-Origin "https://example.com"
感谢@Craig Scott 提示帮我解决
可怜的、没有经验的处理 AMP 页面的人有祸了。
对于使用 nodejs 的人,语法如下:
res.set('AMP-Redirect-To', encodedUrl);
res.set('Access-Control-Allow-Origin', websiteHostname);
res.set('AMP-Access-Control-Allow-Source-Origin', websiteHostname);
res.set('Access-Control-Expose-Headers', [
'AMP-Access-Control-Allow-Source-Origin',
'AMP-Redirect-To',
]);
res.set('Access-Control-Allow-Credentials', 'true');
ِ另一个解决方案是使用 amp-toolbox-cors
库并将其 verifyOrigin
选项设置为 false
。
import ampCors from 'amp-toolbox-cors';
app.use(
ampCors({
verifyOrigin: false,
}),
);
注意所有来源都是这样的。实际上你应该只允许两个。
希望以后能节省一些人的时间!