使用 oEmbed 以編程方式發現共享代碼

已發表: 2022-03-10
快速總結 ↬許多網站託管了可以通過使用一些 HTML 嵌入代碼在其他地方共享的媒體和內容。 如果您只有項目的 URL,並且需要在沒有人工干預的情況下查找媒體的可嵌入版本,會發生什麼情況? 這就是 oEmbed 的用武之地。

網絡充滿了承載豐富內容的服務,例如視頻、圖像、音樂和播客、地圖和圖表,以及各種不同的樂趣。 很有可能,當您將內容添加到站點時,它會為您提供一種將內容嵌入到其他網頁中的方法。

像 YouTube 這樣的網站有自己的嵌入式播放器,在博客文章甚至產品頁面中很受歡迎。 Soundcloud 有將他們的音樂播放器嵌入你樂隊網站的代碼。 慈善籌款人可能會將他們的大型比賽路線上傳到 Strava 等網站,並希望在他們的籌款網站上分享給他們的讚助商。

所有這一切都是通過在託管站點上找到共享選項並複制一些通常是 HTML 和 JavaScript 混合的代碼來完成的。 然後通常可以將該代碼粘貼到目標頁面中,託管站點將為您的所有朋友、客戶和聯繫人提供豐富的內容表示形式。

到目前為止,一切都很好,這很好地涵蓋了手動嵌入內容的選項。 然而,還有一個明顯的第二個用例,其結果是相同的,但通往它的途徑卻大不相同。

跳躍後更多! 繼續往下看↓

以編程方式共享

假設您正在構建一個接受用戶內容的應用程序或網站。 這可能是簡單的,比如員工與同事分享新聞的基本 Intranet 頁面,也可能是大型社交網絡,人們可以在其中註冊並開始發帖。

在這兩種情況下,如果用戶添加 URL 作為內容的一部分,您需要弄清楚該怎麼做。 你可以想像這樣的場景:

 Check out this video! https://youtu.be/jw7bRnFbwAI

此時,作為發布系統,您需要弄清楚該怎麼做。 第一個選項是什麼都不做,只是將 URL 保留為純文本。 這不是一個好主意,因為用戶通常希望單擊 URL,而純文本無法幫助他們到達另一端的頁面。

第二種選擇是把它變成一個鏈接。 這是一個很好的下一步,因為用戶可以點擊鏈接並獲取內容。 但這樣做時,他們會離開您的網站,並且可能不會很快回來。

最好的用戶體驗可能是能夠獲取該內容的播放器並將其嵌入其中,而不僅僅是 URL。 這將使用戶能夠直接在您的網站中體驗內容,就像他們在 Facebook 上一樣。

這就提出了問題。 給定一個 URL,我如何將其轉換為在頁面上顯示富播放器所需的 HTML/JavaScript 嵌入代碼?

如果它是 YouTube 之類的知名網站,我可以編寫一些代碼,使用 YouTube API 來獲取視頻信息並以這種方式獲取或構建嵌入代碼。 我可以對 Vimeo 和 VIVO 等其他視頻服務做同樣的事情。 我可以編寫代碼來識別 Flickr 和 Instagram 的 URL,並使用它們的 API 來獲取漂亮的可嵌入版本的照片。 Twitter 和推文也是如此。 但這聽起來像很多工作!

理想的情況是,如果有一種標準化的方法可以從一段內容的 URL 獲取到嵌入代碼塊,以在頁面上顯示該內容。 如果您一直在關注,您會發現答案就是 oEmbed。

oEmbed 的由來

這正是 Leah Culver 在 Pownce(一個真正創新的社交網站,是 Twitter 的 VHS 的 Betamax)工作時遇到的問題。 Pownce 希望將豐富的內容表示嵌入到用戶的更新流中,但不想將支持僅限於他們專門編寫代碼以與之集成的服務。 在與同事 Mike Malone 以及 Cal Henderson(他在 Flickr 領導工程——當時是此類內容的主要提供商之一)和 Richard Crowley 共進晚餐時,他們一起討論了一個用於獲取嵌入代碼的開放標準的想法一個網址。 Henderson 離開並根據討論起草了一些東西,oEmbed 誕生了。

使用 oEmbed

這是它的工作原理。

它以指向單個內容項的 URL 開頭。 這可能是 YouTube 視頻、圖像或其他任何內容。 通常,這將由您的網站或應用程序的用戶作為他們希望發布的某些內容的一部分提供。 第一步是獲取該 URL 的頁面內容,該 URL 應該是一個 HTML 頁面。

如果託管內容的站點支持 oEmbed,則在該頁面的<head>部分中應該有一個帶有oembed內容類型的link元素:

 <link rel="alternate" type="application/json+oembed" href="https://youtube.com/oembed?url=https%3A%2F%2Fyoutu.be%2Fjw7bRnFbwAI&format=json" title="Inclusive Components with Heydon Pickering" />

關於 XML 的說明: oEmbed 支持 XML 和 JSON 格式的響應。 對於本文,我只考慮 JSON,因為我們不是野蠻人。 如果您不幸需要使用 XML,請注意它是 oEmbed 規範支持的格式,儘管您可能會發現某些提供程序僅提供 JSON 響應。

此鏈接標記作為rel屬性設置為alternatetype設置為application/json+oembedtext/xml+oembed 。 正是這個屬性讓我們知道在href中給出的 URL 實際上是一個 oEmbed API 端點,用於檢索內容的詳細信息。

該 URL 通常有兩個參數: urlformat

範圍價值
url (必填) 內容項的 URL 編碼網址
format 您希望響應的格式jsonxml之一

初始消費者請求的通用 URL 參數

完整的規範在此處進行了更詳細的介紹(如果創建自己的實現,您應該參考它),但這是您可能會看到最多的兩個參數。

因此,我們得到了一個 URL,獲取了頁面,找到了一個 oEmbed 鏈接標籤,其中包含另一個用於 API 端點的 URL。 接下來,我們請求該新 URL,它會返回服務必須提供的有關該內容的所有信息。

 { "author_name": "Smashing Magazine", "width": 480, "title": "Smashing TV: Inclusive Components with Heydon Pickering (Nov 7th 2019)", "provider_name": "YouTube", "height": 270, "html": "<iframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/jw7bRnFbwAI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>", "provider_url": "https://www.youtube.com/", "thumbnail_url": "https://i.ytimg.com/vi/jw7bRnFbwAI/hqdefault.jpg", "type": "video", "thumbnail_height": 360, "author_url": "https://www.youtube.com/channel/UCSDtqcJ8ZXviPrEcj1vuLiQ", "version": "1.0", "thumbnail_width": 480 }

現在我們在說話! 響應為我們提供了有關內容的大量信息。 在可預見的將來, version應該是1.0 ,這是 oEmbed 規範的當前版本。 返回的其他信息很大程度上取決於type的值。

響應類型

響應中type鍵的值告訴您要嵌入哪種媒體。

type期待什麼
photo 提供可用於基本img標籤的urlwidthheight的靜態照片
video 一個視頻播放器,帶有html指定在頁面上嵌入播放器所需的代碼,儘管具有widthheight
link 畢竟,處理這些內容的最好方法就是提供一個鏈接。 響應可能有其他有用的信息,如標題,但它應該只是鏈接起來。
rich 某種內容豐富的播放器,就像視頻類型一樣返回htmlwidthheight

除了專用視頻內容之外,您可能在野外看到的更常見的類型是rich 。 即使是 Flickr 本身,在仍然發送photo響應的同時,也為圖像的豐富可嵌入“播放器”提供html

大多數情況下,將內容嵌入您的網站只是使用提供的代碼作為html值的一種情況。

關於安全的說明

您可能正確謹慎的一件事是獲取 HTML 響應並將其以編程方式嵌入到您託管的頁面中。 如果沒有人為的步驟來仔細檢查您粘貼的代碼,那麼該代碼總是有可能是惡意的。 因此,您應該採取適當的措施來降低風險。

這可能包括過濾 URL 以確保方案和域與預期匹配,以及將代碼沙箱化到不同的無 cookie 域上的 iframe 中。 您應該了解您使用代碼的情況,並確保您沒有將自己暴露在不適當的風險中。

入門

儘管在使用 oEmbed 時理解流程很重要,但現實情況是,大多數常用語言都有可用的庫來抽象流程並使其相對簡單。

例如,npm 打包的 oembed 提供了一個非常簡單的接口,用於根據內容 URL 發出請求並返回 oEmbed 響應。

首先將包安裝到您的項目中:

 npm i oembed

然後請求 URL。 在這裡,我使用了關於 oEmbed 的 Notist 演示文稿的 URL。 多麼元。

 const oembed = require('oembed'); const url = 'https://noti.st/drewm/ZOFFfI'; oembed.fetch(url, { maxwidth: 1920 }, function(error, result) { if (error) console.error(error); else console.log("oEmbed result", result); });

和回應:

 { type: 'rich', version: '1.0', title: 'Understanding oEmbed', author_name: 'Drew McLellan', author_url: 'https://noti.st/drewm', provider_name: 'Notist', provider_url: 'https://noti.st', cache_age: 604800, thumbnail_url: 'https://on.notist.cloud/slides/deck4179/large-0.png', thumbnail_width: 1600, thumbnail_height: 900, html: '<p data-notist="drewm/ZOFFfI">View <a href="https://noti.st/drewm/ZOFFfI">Understanding oEmbed</a> on Notist.</p><script async src="https://on.notist.cloud/embed/002.js"></script>', width: 960, height: 540 }

如果你想在 PHP 中做同樣的事情,可以通過 Composer 安裝一個名為 embed/embed 的方便的包。

 composer require embed/embed

然後在您的 PHP 項目中:

 use Embed\Embed; $info = Embed::create('https://noti.st/drewm/ZOFFfI'); $info->title; // "Understanding oEmbed" $info->authorName; // "Drew McLellan $info->code; // "<p data-notist="drewm/ZOFFfI"> ... </script>"

如您所見,使用庫,該過程變得非常簡單,您可以快速從 URL 獲取嵌入代碼,準備顯示用戶內容的豐富表示。

結論

oEmbed 是一個非常優雅的解決方案,可以解決非常具體的問題。 您會認為只有少數在大型社交網絡上工作的工程師會從中受益,這是可以原諒的,但實際上,用戶可能輸入 URL 的發布系統非常普遍。 給我找一位在某些時候不需要構建某種 CMS 的後端工程師。 我們可能不會以相同的方式考慮它,但如果您接受用戶輸入,您應該考慮如果該輸入包含 URL 該怎麼辦。

既然您了解了 oEmbed(抱歉),您就沒有理由不認真考慮在未來項目中如何處理 URL。

  • o嵌入規範
  • 用於 NodeJS 的 oembed
  • 嵌入/嵌入 PHP
  • “宣布 OEmbed:嵌入式內容的開放標準”,Leah Culver