CloudFront 上基于设备的重定向从 S3 源服务
Device based redirection on CloudFront serving from S3 origin
有没有一种方法可以使用 CloudFront 将用户重定向到基于 User Agent
header 的 Web 应用程序 m.foobar.com
的移动版本?
我确实阅读了 header 使用 CloudFront-Is-Mobile-Viewer
header 使用用户设备类型的缓存。但是,如果我使用自定义来源来为我的资产(ELB 或 EC2 实例)提供服务,我只能将其列入白名单。在这种情况下,我可以编辑我的服务器配置来处理重定向。
但是,我现在正在使用 S3 为我的应用程序提供服务,并且更喜欢 CloudFront/S3 生态系统中的解决方案。
编辑:
对于 S3 发行版,我无权访问 CloudFront-Is-Mobile-Viewer
和其他 CF header。
任何帮助,指点将不胜感激!
背景Material:http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html
https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/
这是我的解决方法。
您不需要为移动应用执行重定向。 (尽可能避免重定向)您可以使用相同的 url 来提供桌面或移动内容。
在您的云端白名单中,只需将 CloudFront-Is-Mobile-Viewer
header 列入白名单。这将根据您的设备缓存内容。
实施 Viewer Request Lambda Edge 并将其添加到 CloudFront。
Lambda Edge 是在请求到达服务器之前对 pop 或 CloudFront 进行编程。
在 LambdaEdge 中,验证 User-Agent header 并对您要提供移动内容还是桌面内容进行分类。如果是移动设备,那么您可以更改来源 url 以从移动内容提供服务,否则您可以将其更改为桌面内容或默认内容。
您在用户请求 LambdaEdge 中获得了您的 http headers。
Lambda Edge 文档:
http://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html
参考页面上提供了示例节点实现。
如果您真的想执行重定向,您可以使用查看器响应并在设备 header 上接收 decision-based。
查看器响应的示例实现包含在本博客中,
https://aws.amazon.com/blogs/aws/lambdaedge-intelligent-processing-of-http-requests-at-the-edge/
上面的实现只是吐回它收到的所有 header,而不是发送 200 OK,代码需要修改为带有重定向位置的 3xx 状态。
希望对您有所帮助。
这是我的解决方法。
Lambda@Edge 函数
'use strict';
exports.handler = (event, context, callback) => {
/*
* If mobile, redirect to mobile domain
*/
const isMobileHeader = 'CloudFront-Is-Mobile-Viewer'
const request = event.Records[0].cf.request;
const headers = request.headers;
let response = event.Records[0].cf.response;
if (headers[isMobileHeader.toLowerCase()] && headers[isMobileHeader.toLowerCase()] == "true") {
response = {
status: '302',
statusDescription: 'Found',
headers: {
location: [{
key: 'Location',
value: 'http://m.foobar.com',
}],
},
};
callback(null, response);
};
CloudFront 分布
Behaviours:
Default:
Cache Based on Selected Request Headers: Whitelist
Whitelist Headers:
- CloudFront-Is-Mobile-Viewer
Lambda Function Associations:
Event Type: Viewer Response
Lambda Function ARN: [ARN of function from Lambda@Edge Function]
进一步阅读
编辑 1
原来是 S3 Origins,正如 Sanjay 指出的那样 limited to a select set of headers for caching。
我对此的建议是使用 S3 Static Website hosting 从 S3 来源更改为自定义来源,然后我们可以将其定位为自定义来源。
S3 存储桶配置
S3 Bucket:
Properties:
Static Website Hosting: Use this bucket to host a website
记下您在此页面上提供的端点名称,下一步将需要它。
CloudFront 更新
Origins:
Create Origin:
Origin Domain Name: [Endpoint from above]
Origin ID: Custom-S3StaticHosting
Behaviours:
Default:
Origin: Custom-S3StaticHosting
目前在 观众响应 我们无法访问 CloudFront-Is-X-Viewer header 甚至在将它们设置为白名单后 状态 header 是read-only。我已经通过在 origin request:
触发解决了这个问题
exports.handler = (event, context, callback) => {
const name = 'cloudfront-is-mobile-viewer';
const request = event.Records[0].cf.request;
const headers = request.headers;
if (headers[name] && headers[name][0].value == "true") {
callback(null, {
status:'302',
statusDescription: 'Found',
headers: {
location: [{
key: 'Location',
value: `http://m.example.com${request.uri}`,
}]
}
})
}
callback(null, request);
};
如何使用此代码为 nodejs 添加解码器,我使用此代码但它给了我一个字符串(如何解码它的 URi 字符串)
对不起,我把它添加到回答中,因为我的声誉很低
exports.handler = (event, context, callback) => {
const name = 'cloudfront-is-mobile-viewer';
const request = event.Records[0].cf.request;
const headers = request.headers;
if (headers[name] && headers[name][0].value == "true") {
callback(null, {
status:'302',
statusDescription: 'Found',
headers: {
location: [{
key: 'Location',
value: `http://m.example.com${request.uri}`,
}]
}
})
}
回调(空,请求);
};
有没有一种方法可以使用 CloudFront 将用户重定向到基于 User Agent
header 的 Web 应用程序 m.foobar.com
的移动版本?
我确实阅读了 header 使用 CloudFront-Is-Mobile-Viewer
header 使用用户设备类型的缓存。但是,如果我使用自定义来源来为我的资产(ELB 或 EC2 实例)提供服务,我只能将其列入白名单。在这种情况下,我可以编辑我的服务器配置来处理重定向。
但是,我现在正在使用 S3 为我的应用程序提供服务,并且更喜欢 CloudFront/S3 生态系统中的解决方案。
编辑:
对于 S3 发行版,我无权访问 CloudFront-Is-Mobile-Viewer
和其他 CF header。
任何帮助,指点将不胜感激!
背景Material:http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/
这是我的解决方法。
您不需要为移动应用执行重定向。 (尽可能避免重定向)您可以使用相同的 url 来提供桌面或移动内容。
在您的云端白名单中,只需将 CloudFront-Is-Mobile-Viewer
header 列入白名单。这将根据您的设备缓存内容。
实施 Viewer Request Lambda Edge 并将其添加到 CloudFront。 Lambda Edge 是在请求到达服务器之前对 pop 或 CloudFront 进行编程。
在 LambdaEdge 中,验证 User-Agent header 并对您要提供移动内容还是桌面内容进行分类。如果是移动设备,那么您可以更改来源 url 以从移动内容提供服务,否则您可以将其更改为桌面内容或默认内容。
您在用户请求 LambdaEdge 中获得了您的 http headers。
Lambda Edge 文档:
http://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html
参考页面上提供了示例节点实现。
如果您真的想执行重定向,您可以使用查看器响应并在设备 header 上接收 decision-based。
查看器响应的示例实现包含在本博客中,
https://aws.amazon.com/blogs/aws/lambdaedge-intelligent-processing-of-http-requests-at-the-edge/
上面的实现只是吐回它收到的所有 header,而不是发送 200 OK,代码需要修改为带有重定向位置的 3xx 状态。
希望对您有所帮助。
这是我的解决方法。
Lambda@Edge 函数
'use strict';
exports.handler = (event, context, callback) => {
/*
* If mobile, redirect to mobile domain
*/
const isMobileHeader = 'CloudFront-Is-Mobile-Viewer'
const request = event.Records[0].cf.request;
const headers = request.headers;
let response = event.Records[0].cf.response;
if (headers[isMobileHeader.toLowerCase()] && headers[isMobileHeader.toLowerCase()] == "true") {
response = {
status: '302',
statusDescription: 'Found',
headers: {
location: [{
key: 'Location',
value: 'http://m.foobar.com',
}],
},
};
callback(null, response);
};
CloudFront 分布
Behaviours:
Default:
Cache Based on Selected Request Headers: Whitelist
Whitelist Headers:
- CloudFront-Is-Mobile-Viewer
Lambda Function Associations:
Event Type: Viewer Response
Lambda Function ARN: [ARN of function from Lambda@Edge Function]
进一步阅读
编辑 1
原来是 S3 Origins,正如 Sanjay 指出的那样 limited to a select set of headers for caching。
我对此的建议是使用 S3 Static Website hosting 从 S3 来源更改为自定义来源,然后我们可以将其定位为自定义来源。
S3 存储桶配置
S3 Bucket:
Properties:
Static Website Hosting: Use this bucket to host a website
记下您在此页面上提供的端点名称,下一步将需要它。
CloudFront 更新
Origins:
Create Origin:
Origin Domain Name: [Endpoint from above]
Origin ID: Custom-S3StaticHosting
Behaviours:
Default:
Origin: Custom-S3StaticHosting
目前在 观众响应 我们无法访问 CloudFront-Is-X-Viewer header 甚至在将它们设置为白名单后 状态 header 是read-only。我已经通过在 origin request:
触发解决了这个问题exports.handler = (event, context, callback) => {
const name = 'cloudfront-is-mobile-viewer';
const request = event.Records[0].cf.request;
const headers = request.headers;
if (headers[name] && headers[name][0].value == "true") {
callback(null, {
status:'302',
statusDescription: 'Found',
headers: {
location: [{
key: 'Location',
value: `http://m.example.com${request.uri}`,
}]
}
})
}
callback(null, request);
};
如何使用此代码为 nodejs 添加解码器,我使用此代码但它给了我一个字符串(如何解码它的 URi 字符串) 对不起,我把它添加到回答中,因为我的声誉很低
exports.handler = (event, context, callback) => {
const name = 'cloudfront-is-mobile-viewer';
const request = event.Records[0].cf.request;
const headers = request.headers;
if (headers[name] && headers[name][0].value == "true") {
callback(null, {
status:'302',
statusDescription: 'Found',
headers: {
location: [{
key: 'Location',
value: `http://m.example.com${request.uri}`,
}]
}
})
}
回调(空,请求); };