跳到正文
DEV Community· Sangyoon Lee·· 3 小時前AI 評分54

Figma 插件 UI 的 origin 為 null:如何無需伺服器或 API key 讀取 Google Sheet

Figma plugin UI has a null origin: how I read a Google Sheet without a server or API key

AI 導讀

作者在 Figma 插件的 null-origin UI 中,以 script tag 載入 Google Sheet 的 JSON-with-callback 格式,成功讀取公開試算表,無需伺服器或 API key。

正文

Sangyoon Lee

I was building a Figma plugin that pulls rows from a public Google Sheet. It looked easy: fetch the CSV, parse it, done. It did not work, and the reason is easy to miss.

The problem

A Figma plugin UI runs in an iframe with a null origin. The Figma docs say this means the plugin can only call APIs that return Access-Control-Allow-Origin: *.

I built a sandboxed iframe with a null origin and tested each way to read the sheet.

Path Result
docs.google.com gviz/tq?tqx=out:csv blocked
docs.google.com export?format=csv blocked
sheets.googleapis.com v4 works, but needs an API key
gviz/tq?tqx=out:json;responseHandler:cb loaded with a script tag works, no key, no server

Why the export URL fails

The final response of the export URL does have the allow header. But the first answer is a 307 redirect, and that redirect has no allow header. The browser checks the first one and stops.

What worked

A script tag is not subject to CORS. So I ask Google for the JSON-with-callback format and load it as a script:

window.cb = (data) => { /* data.table.rows */ };
const s = document.createElement("script");
s.src = "https://docs.google.com/spreadsheets/d/<ID>/gviz/tq?tqx=out:json;responseHandler:cb&headers=0";
document.body.appendChild(s);

Add headers=0, otherwise Google guesses which row is the header and may eat your first data row.

Lesson

Before writing any code that reads someone else's API from a browser extension or plugin, check with curl whether the API sends Access-Control-Allow-Origin: *. If there is a redirect, look at the headers of the first response, not the last one.

The built-in browser pane of my tool could not run nested sandbox iframes, so I had to do this test in a real Chrome. Testing in the real environment saved me from shipping a plugin that fails on first load.

Have you hit a null-origin problem in another plugin platform, and how did you get around it?


I'm a full-stack developer, 13 years, based in Korea (UTC+9). I work in writing only, and use AI translation, so my English is simple. CV: https://cv.namubase.com

來源:DEV Community · dev.to