You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript设置YouTube视频缩略图?401无效凭证问题解决

Fixing YouTube Thumbnail Upload 401 Invalid Credentials Error

Hey there, let's break down why you're hitting that 401 error and get your thumbnail upload working properly. Here are the core issues with your current code and how to fix them:

1. Your Access Token Is Invalid or Missing Required Permissions

The 401 error almost always points to problems with your Bearer token:

  • Wrong token type: API Keys won't work here—you need an OAuth 2.0 Access Token (generated via OAuth flow for the user who owns the video). API Keys only grant read access to public data, not write permissions like setting thumbnails.
  • Missing scopes: When requesting your OAuth token, you must include either https://www.googleapis.com/auth/youtube or https://www.googleapis.com/auth/youtube.upload scope. Without these, the token won't have permission to modify video thumbnails.
  • Expired token: OAuth access tokens expire after 1 hour. Verify your token is still valid using Google's token validation tools in the Cloud Console.

2. Incorrect Request URL & Resumable Upload Flow

Your current code skips a critical step in YouTube's resumable upload process:

  • Fixed URL: Replace & with & in your URL—& is HTML entity encoding, which doesn't work in raw JS requests.
  • Two-step resumable upload: You can't send the file directly in the initial POST. First, request an upload session URL, then use that URL to send the file via PUT.

Corrected Code Example

Here's the full working code that follows YouTube's API requirements:

const fileInput = document.getElementById("file");
const file = fileInput.files[0];

if (!file) {
  console.error("Please select an image file first!");
  return;
}

// Step 1: Initialize a resumable upload session
const initSession = new XMLHttpRequest();
initSession.open(
  "POST",
  "https://www.googleapis.com/upload/youtube/v3/thumbnails/set?videoId=YOUR_VIDEO_ID&uploadType=resumable",
  true
);

// Set required headers for session initialization
initSession.setRequestHeader("Authorization", "Bearer YOUR_VALID_OAUTH_ACCESS_TOKEN");
initSession.setRequestHeader("X-Upload-Content-Type", file.type); // Matches your image's MIME type (e.g., image/jpeg)
initSession.setRequestHeader("Content-Length", 0); // Empty body for initialization

initSession.onload = function () {
  if (initSession.status === 200 || initSession.status === 201) {
    // Get the unique upload session URL from the response headers
    const uploadUrl = initSession.getResponseHeader("Location");
    // Step 2: Upload the thumbnail file using the session URL
    uploadThumbnail(uploadUrl, file);
  } else {
    console.error("Session init failed:", initSession.responseText);
  }
};

initSession.onerror = function () {
  console.error("Failed to connect to YouTube API for session init");
};

initSession.send();

// Helper function to upload the actual image file
function uploadThumbnail(uploadUrl, file) {
  const uploadReq = new XMLHttpRequest();
  uploadReq.open("PUT", uploadUrl, true);
  uploadReq.setRequestHeader("Content-Type", file.type);

  uploadReq.onload = function () {
    if (uploadReq.status === 200) {
      console.log("Thumbnail updated successfully!", uploadReq.responseText);
    } else {
      console.error("Thumbnail upload failed:", uploadReq.responseText);
    }
  };

  uploadReq.onerror = function () {
    console.error("Failed to upload thumbnail file");
  };

  uploadReq.send(file);
}

Additional Checks to Avoid Future Errors

  • Verify OAuth client settings: Make sure your OAuth client ID in the Google Cloud Console has your domain (or http://localhost for testing) added to the allowed JavaScript origins.
  • Double-check video ID: Ensure YOUR_VIDEO_ID matches a video you own—you can't set thumbnails for videos you don't have edit access to.

内容的提问来源于stack exchange,提问作者JimmyN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:49:02