可以使用JavaScript更改页面的meta标签吗?

167
如果我在head中插入一个display:none的div,然后使用JavaScript将其显示出来,这样能行吗?
编辑:
我有一些通过AJAX加载的内容。当我的AJAX更改了网站的“主要”部分时,我也想同时更改meta标签。

52
这就像是把鞋子当作帽子戴一样。 - Ben
9
或者使用文本编辑器作为集成开发环境。等等,这被认为很酷。 - Dan Rosenstark
23
你说得对,我很愚蠢。 - TIMEX
2
嗨TIMEX,也许更改接受的答案是合适的吗?如果没有其他原因,只是为了让Byron在过时的答案上得到一些喘息时间。 - Alex
1
我想这样做是为了使用我的JavaScript框架管理元标签(特别是og),然后让我的预渲染引擎为爬虫编写/缓存此内容。否则,我需要额外的中间件来确定我的API中的标签,然后再呈现我的SPA索引,这会拖慢加载速度,其中之一... - Soft Bullets
显示剩余4条评论
20个回答

251

是的,没错。

例如,设置元描述:

document.querySelector('meta[name="description"]').setAttribute("content", _desc);

47
很高兴有人提供了纯js的答案(正如问题中所要求的)! - Soft Bullets
嗨jayms。感谢你的提示。但是我尝试了这种方法来更改og:title标签,但没有成功。这是我的做法:document.querySelector('meta[name="og:title"]').setAttribute("content", "Example with title meta tag"); 有什么想法吗? - Jorge Mauricio
8
看起来你需要查询property属性,而不是name属性,即 meta[property="og:title"] - jayms

162

是的,你可以这样做。

有一些有趣的用例:一些浏览器和插件解析meta元素,并根据不同的值改变它们的行为。

示例

Skype:关闭电话号码解析器

<meta name="SKYPE_TOOLBAR" content="SKYPE_TOOLBAR_PARSER_COMPATIBLE">

iPhone:关闭电话号码解析器

<meta name="format-detection" content="telephone=no">

谷歌Chrome框架

<meta http-equiv="X-UA-Compatible" content="chrome=1">

移动设备的视口定义

<meta name="viewport" content="width=device-width, initial-scale=1.0">

这里的内容可以通过 JavaScript 进行更改。参见:解决 iPhone 视口比例缩放 Bug 的方法

元描述

一些用户代理(例如 Opera)将描述用于书签。您可以在此处添加个性化内容。例如:

<!DOCTYPE html>
<title>Test</title>
<meta name="description" content="this is old">
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.js'></script>

<button>Change description</button>

<script type='text/javascript'>
$('button').on('click', function() {
    // Just replacing the value of the 'content' attribute will not work.
    $('meta[name=description]').remove();
    $('head').append( '<meta name="description" content="this is new">' );
});
</script>

所以,这不仅仅是关于搜索引擎。


10
我怀疑大多数这样的元标记一旦页面加载后就无法更改其效果。但是,没错,meta标记远不止于keywordsdescription - bobince
2
@bobince:实际上,如果您使用js插入SKYPE_TOOLBAR,则仍然会生效(这很有用,因为html5验证器不喜欢该元标记)。 - DaedalusFall
1
@DaedalusFall:是的,我认为你只能在头部使用document.write来做到这一点,一旦页面加载完成,要改变它就太晚了,因为Skype已经破坏了DOM结构,真是可怕的事情! - bobince
1
这对于社交分享到Facebook等服务非常有用。例如,要更改og:title元素:$('meta [property ="og:title"]').replaceWith('<meta property ="og:title" content ="New Title">'); - bdanin
3
你可以使用这个功能做一些很酷的事情。当标题幻灯片改变时,我会更改Chrome地址栏的颜色。 const meta = document.querySelector('meta[name=theme-color]'); meta.setAttribute("content", colors[slideIndex]); 安卓上的Chrome会检测到更新并更改颜色。 - Dominic
显示剩余3条评论

73
您可以使用类似下面这样的代码(使用jQuery):
$('meta[name=author]').attr('content', 'New Author Name');

但这样做大多是毫无意义的,因为元标记通常只在加载文档时被抓取,通常不会执行任何JavaScript。


7
它甚至可以与选择器一起使用,例如 $('meta[property=og:somestuff]'),我怀疑它会因为冒号而与jQuery的选择语法发生冲突。 - pau.moreno
8
如果有人正在寻找与此完全相同的解决方案,你需要在og:somestuff周围加上引号-我需要图像标签的内容,这是我的代码: var imgurl = $(“meta[property ='og:image']”)。attr(“content”); - Daniel
2
已确认它适用于meta viewport设置(需要此设置才能在jQuery Mobile上启用/禁用某些子页面的缩放)。谢谢! - NPC
1
@stealthcopter 我可以验证这个不起作用 :( 等等,它确实起作用了,但是在FFox的“查看源代码”窗口中更改是不可见的..? - yPhil
1
@yPhil 这是 JavaScript(或 jQuery),因此对 DOM 所做的任何更改在从浏览器查看源代码时不会反映出来。只有在使用开发人员工具查看源代码时才会反映出来。浏览器源仅在页面加载时加载一次。ajax 请求不是页面加载。 - Zubair1
显示剩余3条评论

56

使用JavaScript更改页面的meta标签绝对是可行的。以下是一种仅使用JavaScript的方法:

document.getElementsByTagName('meta')["keywords"].content = "My new page keywords!!";
document.getElementsByTagName('meta')["description"].content = "My new page description!!";
document.title = "My new Document Title!!";

我已经验证了Google确实会为上述代码中的客户端更改编制索引。


4
有趣!感谢让我了解element = collection[name]语法。 - jayms
确保关键词和描述的元标记与标题存在,上述内容将正常工作。https://codepen.io/tmoses/pen/RwaZOXo(请参见console.log输出) - Tim
我测试了上面的代码,将其放置在头部和页脚附近的脚本标签中(显然我知道),但它对我不起作用。我知道问题出在我身上,但却束手无策。 - user1469
请在CodePen或类似的平台上模拟您的设置并发送链接。 - Tim

33

您可以使用jQuery调用来更改元标记,例如:

$('meta[name=keywords]').attr('content', new_keywords);
$('meta[name=description]').attr('content', new_description);

我认为现在它确实很重要,因为 Google 表示他们将通过使用#!hashes_escaped_fragment_来索引ajax内容,并且现在他们可以验证它(甚至自动地,使用无头浏览器,参见上面提到的“创建HTML快照”链接),所以我认为这是极客级别SEO人员的方法。


3
谢谢您。这正好解决了我的问题。由于Facebook拥有开放图谱,我正在开发的网站具有历史记录jQuery插件和哈希标签。因此,每当存在哈希更改时,FB开放图谱的URL和描述都需要更改。对于很棒的答案并且没有对一个公平问题持否定态度,点赞+1。 - Damien Keitel
5
实际上,现在谷歌也能够运行JavaScript,而无需创建页面快照,因此动态元标记现在非常重要! - Francesco Abbruzzese

18

你可以使用更简单、更轻巧的解决方案:

document.head.querySelector('meta[name="description"]').content = _desc

13
标签是DOM的一部分,可以被访问和更改,但搜索引擎(主要是标签的使用者)不会看到更改,因为JavaScript不会被执行。所以除非你更改的是一个在浏览器中具有影响的标签(例如“refresh”),否则这可能没有太大用处?

3
+1 - 我找到这个问题是因为我对 meta refresh 特别感兴趣。我正在创建一个应用程序,使用 ajax 轮询来刷新屏幕上的数据,并希望为没有启用 JavaScript 的浏览器提供一个简单的回退方案。我考虑默认创建一个 meta refresh 标签,如果启用了 JavaScript,就删除该标签。现在看看它是否真正起作用... - jessegavin
1
@futtta,meta描述标签用于在Opera中的书签描述,因此您的meta描述可以更改,实际上对用户有好处。 - XP1

11

你可以像下面这样做(或者使用jQuery,例如 $('meta[name=author]').attr("content");):

<html>
<head>
<title>Meta Data</title>
<meta name="Author" content="Martin Webb">
<meta name="Author" content="A.N. Other">
<meta name="Description" content="A sample html file for extracting meta data">
<meta name="Keywords" content="JavaScript, DOM, W3C">

</head>

<body>
<script language="JavaScript"><!--
if (document.getElementsByName) {
  var metaArray = document.getElementsByName('Author');
  for (var i=0; i<metaArray.length; i++) {
    document.write(metaArray[i].content + '<br>');
  }

  var metaArray = document.getElementsByName('Description');
  for (var i=0; i<metaArray.length; i++) {
    document.write(metaArray[i].content + '<br>');
  }

  var metaArray = document.getElementsByName('Keywords');
  for (var i=0; i<metaArray.length; i++) {
    document.write(metaArray[i].content + '<br>');
  }
}
//--></script>
</body>

</html>

11
$(document).ready(function() {
  $('meta[property="og:title"]').remove();
  $('meta[property="og:description"]').remove();
  $('meta[property="og:url"]').remove();
  $("head").append('<meta property="og:title" content="blubb1">');
  $("head").append('<meta property="og:description" content="blubb2">');
  $("head").append('<meta property="og:url" content="blubb3">');
});

6
我从你的示例开始,但意识到你不必删除和重新添加元标签。你只需要像这样更改内容属性:jQuery('meta[property="og:title"]').attr('content', "blubb1"); - Tobias Beuving
你是正确的,@user3320390。删除标签与更改标签是不同的。FB根据HTML编写的内容进行操作,而不是标签的值。 - Pedro Ferreira

7

name属性允许您通过子元素列表引用一个元素的名称(类似于id),因此快速的方法是:

document.head.children.namedItem('description').content = '...'

- 或者仅仅是:

document.head.children.description.content = '...'

但是如果你不确定是否存在这样的元标记,那么最好添加以下检查:

let metaDescription = document.head.children.description
if (metaDescription == null) {
  metaDescription = document.createElement('meta')
  metaDescription.name = 'description'
  document.head.append(metaDescription)
}
metaDescription.content = '...'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接