Heim >Backend-Entwicklung >Golang >Das Hochladen der Datei auf Google Drive über die API schlägt fehl

Das Hochladen der Datei auf Google Drive über die API schlägt fehl

王林
王林nach vorne
2024-02-09 13:30:08460Durchsuche

通过 API 将文件上传到 Google Drive 失败

php-Editor Xigua teilt Ihnen mit, dass es manchmal zu Fehlern kommen kann, wenn wir die API zum Hochladen von Dateien auf Google Drive verwenden. Diese Situation kann verschiedene Ursachen haben, z. B. Netzwerkprobleme, unzureichende Berechtigungen usw. Aber keine Sorge, wir können einiges tun, um dieses Problem zu beheben. Als Nächstes stellen wir Ihnen im Detail vor, wie Sie Dateien über die API erfolgreich auf Google Drive hochladen, damit sich niemand mehr um dieses Problem kümmern muss.

Frageninhalt

Ich versuche, eine Datei auf mein Google Drive hochzuladen, aber es schlägt fehl. Ich dachte, ich hätte den MIME-Typ richtig angegeben, weil ich festgestellt habe, dass dies ein häufiges Problem ist, aber es funktioniert bei mir immer noch nicht.

Über das Konvertierungssystem: Ich habe eine API für Gin-Gonic (v1.9.1), über die ich Dateien hochladen kann. Die Datei wurde erfolgreich vom Frontend/Postboten an die API übergeben, da ich die von der API erhaltene Datei erfolgreich speichern kann.

Der Fehler, den ich erhalte, ist:

Post "https://www.googleapis.com/upload/drive/v3/files?alt=json&prettyPrint=false&uploadType=multipart": Post "": unsupported protocol scheme ""

Ich habe folgende Funktion:

func (c *Client) UploadFile(oauthTokenConfig GoogleOauthTokenConfig, parentFolderId string, fileHeader *multipart.FileHeader) (*string, error) {
    svc, err := drive.NewService(context.Background(), option.WithHTTPClient(
        oauthTokenConfig.Config.Client(
            context.Background(),
            &oauth2.Token{
                AccessToken:  oauthTokenConfig.AccessToken,
                TokenType:    oauthTokenConfig.TokenType,
                RefreshToken: oauthTokenConfig.RefreshToken,
                Expiry:       oauthTokenConfig.ExpiresIn,
            },
        )),
    )
    if err != nil {
        return nil, err
    }

    fileExtension := filepath.Ext(fileHeader.Filename)
    fileName := strings.TrimSuffix(fileHeader.Filename, fileExtension)
    fileMimeType := fileHeader.Header.Get("Content-Type")
    uploadFileMetaData := drive.File{
        Name:     fmt.Sprintf("%s%s", fileName, fileExtension), 
                // fmt.Sprintf("%s_%s%s", fileName, uuid.New().String(), fileExtension),
        Parents:  []string{parentFolderId},
        MimeType: fileMimeType,
    }

    file, err := fileHeader.Open()
    if err != nil {
        return nil, err
    }
    defer file.Close()

    fileResult, err := svc.Files.
        Create(&uploadFileMetaData).
        Media(file, googleapi.ContentType("text/plain")).
        Do()
    if err != nil {
        return nil, err // here I get the error
    }

        // ...

}

Ich habe hier einen hartcodierten MIME-Typ hinzugefügt, aber die Variable fileMimeType ist tatsächlich korrekt. Ich habe eine Test.txt-Datei hochgeladen, die den Inhalt von Test1 enthält (die auch erfolgreich erstellt wurde, als ich sie über Frontend/Postman verschickte). Ich habe auch versucht, den Datei-MIME-Typ dynamisch anzugeben oder den MIME-Typ überhaupt nicht anzugeben, erhalte aber immer das gleiche Ergebnis.

Ich verwende hierfür folgende Pakete:

  • Go-Version: go1.21.1 darwin/arm64
  • go list -m golang.org/x/oauth2: v0.13.0
  • go list -m google.golang.org/api: v0.147.0
    • google.golang.org/api/drive/v3
    • google.golang.org/api/googleapi
    • google.golang.org/api/option

Herausgeber:

Ich habe auch das offizielle Beispiel von Google kopiert, aber es funktioniert immer noch nicht.

Problemumgehung

Der Fehler scheint mit der Authentifizierung zusammenzuhängen. Es ist etwas schwierig, aus diesem Fehler die ungültige Authentifizierung abzuleiten, aber ich musste den Aktualisierungsalgorithmus für das Aktualisierungstoken ein wenig ändern, damit es funktioniert.

Das ist mein Arbeitscode. Beachten Sie, dass Sie vor dem Aufruf von UploadFile() 函数之前,我首先检查 oauthTokenConfig.ExpiresIn prüfen, ob das Token noch gültig ist. Wenn ja, laden Sie die Datei hoch, andernfalls aktualisiere ich zuerst das Token.

Datei-Upload

func (c *Client) UploadFile(oauthTokenConfig GoogleOauthTokenConfig, parentFolderId string, file *multipart.FileHeader) (*string, error) {
    svc, err := drive.NewService(context.Background(), option.WithHTTPClient(
        oauthTokenConfig.Config.Client(
            context.Background(),
            &oauth2.Token{
                AccessToken:  oauthTokenConfig.AccessToken,
                TokenType:    oauthTokenConfig.TokenType,
                RefreshToken: oauthTokenConfig.RefreshToken,
                Expiry:       oauthTokenConfig.ExpiresIn,
            },
        )),
    )
    if err != nil {
        return nil, fmt.Errorf("failed to create drive-service: %s", err.Error())
    }

    fileExtension := filepath.Ext(file.Filename)
    fileName := strings.TrimSuffix(file.Filename, fileExtension)
    uploadFile := drive.File{
        Name:    fmt.Sprintf("%s_%s%s", fileName, uuid.New().String(), fileExtension),
        Parents: []string{parentFolderId},
    }
    fileContent, err := file.Open()
    if err != nil {
        return nil, fmt.Errorf("failed to open file: %s", err.Error())
    }

    fileResult, err := svc.Files.Create(&uploadFile).Media(fileContent).Do()
    if err != nil {
        return nil, fmt.Errorf("failed to create file: %s", err.Error())
    }

    uploadedFile, err := svc.Files.Get(fileResult.Id).Fields("webViewLink").Do()
    if err != nil {
        return nil, fmt.Errorf("failed to get file: %s", err.Error())
    }
    return &uploadedFile.WebViewLink, nil
}

Aktualisierungstoken

func (c *Client) RefreshToken(oauthTokenConfig GoogleOauthTokenConfig) (*GoogleOauthTokenConfig, error) {
    ctx := context.Background()
    config := oauth2.Config{
        ClientID:     c.ClientId,
        ClientSecret: c.ClientSecret,
        RedirectURL:  oauthTokenConfig.Config.RedirectURL,
        Scopes:       []string{"https://www.googleapis.com/auth/drive"},
        Endpoint:     google.Endpoint,
    }

    token := &oauth2.Token{
        AccessToken:  oauthTokenConfig.AccessToken,
        TokenType:    oauthTokenConfig.TokenType,
        RefreshToken: oauthTokenConfig.RefreshToken,
        Expiry:       oauthTokenConfig.ExpiresIn,
    }

    tokenSource := config.TokenSource(ctx, token)

    updatedToken, err := tokenSource.Token()
    if err != nil {
        return nil, err
    }

    return &GoogleOauthTokenConfig{
        Config:       config,
        AccessToken:  updatedToken.AccessToken,
        RefreshToken: updatedToken.RefreshToken,
        ExpiresIn:    updatedToken.Expiry,
        TokenType:    updatedToken.TokenType,
    }, nil
}

Das obige ist der detaillierte Inhalt vonDas Hochladen der Datei auf Google Drive über die API schlägt fehl. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen