我一直在 go 中寻找示例 GAE 脚本从 PageSpeed Insights 的结果截图中获取我的图像并使用 Kohana/Cache 将其保存为 json_decode 对象到 Google 云存储 (GCS)。
使用此方法的原因很简单,因为我发现此 Kohana 模型是将文件写入 GCS 的最便捷方式,尽管我也在寻找其他方式,例如 this使用 Blobstore 将文件写入 GCS在 Go API 文件已被弃用时为它们提供服务,如记录 here .
这是包含屏幕截图图像数据 (base64) 的存储对象的形式,该数据在默认应用程序存储桶中以公共(public)方式保存,对象名称为 images/thumb/mythumb.jpg :
stdClass Object
(
[screenshot] => stdClass Object
(
[data] => _9j_4AAQSkZJRgABAQAAAQABAAD_...= // base64 data
[height] => 240
[mime_type] => image/jpeg
[width] => 320
)
[otherdata] => Array
(
[..] => ..
[..] => ..
)
)
我想获取设置为 public 的图像使用我自定义的 url 如下,通过 go module
进行,我还需要它在特定时间过期,因为我已经设法定期更新图像内容本身:
http://myappId.appspot.com/image/thumb/mythumb.jpg
我在 disptach.yaml 中设置将所有图像请求发送到我的 go 模块
,如下所示:
- url: "*/images/*"
module: go
并在 go.yaml 中设置处理程序以按如下方式处理图像请求:
handlers:
- url: /images/thumb/.*
script: _go_app
- url: /images
static_dir: images
使用这个指令,我得到了所有 /images/ 请求(/images/thumb/ 请求除外)提供来自静态目录的图像,并且 /images/thumb/mythumb.jpg 转到模块应用程序。
所以在名为 thumb.go 的应用程序文件中留下了我必须使用的代码(参见 ????
),如下所示:
package thumb
import(
//what to import
????
????
)
const (
googleAccessID = "<serviceAccountEmail>@developer.gserviceaccount.com"
serviceAccountPEMFilename = "YOUR_SERVICE_ACCOUNT_KEY.pem"
bucket = "myappId.appspot.com"
)
var (
expiration = time.Now().Add(time.Second * 60) //expire in 60 seconds
)
func init() {
http.HandleFunc("/images/thumb/", handleThumb)
}
func handleThumb(w http.ResponseWriter, r *http.Request) {
ctx := cloud.NewContext(appengine.AppID(c), hc)
???? //what code to get the string of 'mythumb.jpg' from url
???? //what code to get the image stored data from GCS
???? //what code to encoce base64 data
w.Header().Set("Content-Type", "image/jpeg;")
fmt.Fprintf(w, "%v", mythumb.jpg)
}
我从一些例子中提取了很多代码,比如 this , this或 this但到目前为止还没有一件作品。我还尝试了 this 中的示例这几乎接近 my case但也没有找到运气。
所以一般情况下,主要是因为缺少在我用????
标记的行上放置的正确代码以及要导入的相关库或路径。我还检查了 GCS permission如果按照描述丢失了某些东西 here和 here .
非常感谢您的帮助和建议。
最佳答案
根据我在您的描述中所读到的内容,似乎唯一相关的部分是实际 Go 代码中的 ????
行。如果情况并非如此,请告诉我。
首先????:“什么代码从url中获取'mythumb.jpg'的字符串”?
通过阅读代码,您希望从类似 http://localhost/images/thumb/mythumb.jpg
的 url 中提取 mythumb.jpg
。 Writing Web Applications 提供了一个工作示例教程:
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
这样
http://localhost:8080/monkeys
打印
Hi there, I love monkeys!
第二个????:“从GCS获取图像存储数据的代码是什么”?
您可能希望使用的 API 方法是 storage.objects.get .
您确实链接到了 JSON API Go Examples 之一对于 Google Cloud Storage,这是一个很好的一般引用,但与您要解决的问题无关。该特定示例是为客户端应用程序组合在一起的(因此 redirectURL = "urn:ietf:wg:oauth:2.0:oob"
行)。此外,此示例使用已弃用/过时的 oauth2 和存储包。
对于想要代表自己访问自己的存储桶的应用程序,最干净(且未弃用)的方法之一是使用 golang/oauth2和 Google APIs Client Library for Go包。
如何通过 golang/oauth2 使用 JSON Web Token auth 进行身份验证的示例包裹是available in the repo :
func ExampleJWTConfig() {
conf := &jwt.Config{
Email: "xxx@developer.com",
// The contents of your RSA private key or your PEM file
// that contains a private key.
// If you have a p12 file instead, you
// can use `openssl` to export the private key into a pem file.
//
// $ openssl pkcs12 -in key.p12 -out key.pem -nodes
//
// It only supports PEM containers with no passphrase.
PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."),
Subject: "user@example.com",
TokenURL: "https://provider.com/o/oauth2/token",
}
// Initiate an http.Client, the following GET request will be
// authorized and authenticated on the behalf of user@example.com.
client := conf.Client(oauth2.NoContext)
client.Get("...")
}
接下来,不要直接使用 oauth2 客户端
,而是使用带有 Google APIs Client Library for Go 的客户端前面提到:
service, err := storage.New(client)
if err != nil {
fatalf(service, "Failed to create service %v", err)
}
注意与过时的 JSON API Go Examples 的相似之处?
在您的处理程序中,您需要使用 func ObjectsService.Get
获取相关对象。 .假设您知道 object
和 bucket
的名称,即。
直接从前面的示例中,您可以使用类似于下面的代码来检索下载链接:
if res, err := service.Objects.Get(bucketName, objectName).Do(); err == nil {
fmt.Printf("The media download link for %v/%v is %v.\n\n", bucketName, res.Name, res.MediaLink)
} else {
fatalf(service, "Failed to get %s/%s: %s.", bucketName, objectName, err)
}
然后,获取文件,或者用它做任何你想做的事。完整示例:
import (
"golang.org/x/oauth2"
"golang.org/x/oauth2/jwt"
"google.golang.org/api/storage/v1"
"fmt"
)
...
const (
bucketName = "YOUR_BUCKET_NAME"
objectName = "mythumb.jpg"
)
func main() {
conf := &jwt.Config{
Email: "xxx@developer.com",
PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."),
Subject: "user@example.com",
TokenURL: "https://provider.com/o/oauth2/token",
}
client := conf.Client(oauth2.NoContext)
service, err := storage.New(client)
if err != nil {
fatalf(service, "Failed to create service %v", err)
}
if res, err := service.Objects.Get(bucketName, objectName).Do(); err == nil {
fmt.Printf("The media download link for %v/%v is %v.\n\n", bucketName, res.Name, res.MediaLink)
} else {
fatalf(service, "Failed to get %s/%s: %s.", bucketName, objectName, err)
}
// Go fetch the file, etc.
}
第三个????:“编码base64数据的代码是什么”?
使用 encoding/base64
非常简单包裹。如此简单,他们包括了一个 example :
package main
import (
"encoding/base64"
"fmt"
)
func main() {
data := []byte("any + old & data")
str := base64.StdEncoding.EncodeToString(data)
fmt.Println(str)
}
希望对您有所帮助。
关于image - 如何使用 go 脚本在 Google-Cloud-Storage 中获取我的图像(base64),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29148777/