我想了解如何使用 <base href="" />对我的网络爬虫很有值(value),所以我测试了几种主要浏览器的组合,最后发现了一些我不理解的双斜线。
如果您不喜欢全部阅读,请跳转到D 和E 的测试结果。所有测试的演示:
http://gutt.it/basehref.php
逐步调用我的测试结果http://example.com/images.html :
A - 多碱基 href
<html>
<head>
<base target="_blank" />
<base href="http://example.com/images/" />
<base href="http://example.com/" />
</head>
<body>
<img src="/images/image.jpg">
<img src="image.jpg">
<img src="./image.jpg">
<img src="images/image.jpg"> not found
<img src="/image.jpg"> not found
<img src="../image.jpg"> not found
</body>
</html>
结论
<base>与 href计数/ 开头的来源以根为目标../向上移动一个文件夹B - 没有尾部斜杠
<html>
<head>
<base href="http://example.com/images" />
</head>
<body>
<img src="/images/image.jpg">
<img src="image.jpg"> not found
<img src="./image.jpg"> not found
<img src="images/image.jpg">
<img src="/image.jpg"> not found
<img src="../image.jpg"> not found
</body>
</html>
结论
<base href>忽略最后一个斜杠后的所有内容,所以 http://example.com/images变成 http://example.com/ C - 应该如何
<html>
<head>
<base href="http://example.com/" />
</head>
<body>
<img src="/images/image.jpg">
<img src="image.jpg"> not found
<img src="./image.jpg"> not found
<img src="images/image.jpg">
<img src="/image.jpg"> not found
<img src="../image.jpg"> not found
</body>
</html>
结论
D - 双斜杠
<html>
<head>
<base href="http://example.com/images//" />
</head>
<body>
<img src="/images/image.jpg">
<img src="image.jpg">
<img src="./image.jpg">
<img src="images/image.jpg"> not found
<img src="/image.jpg"> not found
<img src="../image.jpg">
</body>
</html>
E - 带空格的双斜杠
<html>
<head>
<base href="http://example.com/images/ /" />
</head>
<body>
<img src="/images/image.jpg">
<img src="image.jpg"> not found
<img src="./image.jpg"> not found
<img src="images/image.jpg"> not found
<img src="/image.jpg"> not found
<img src="../image.jpg">
</body>
</html>
两者都不是“有效”的 URL,而是我的网络爬虫的真实结果。请解释在 D 和 E 中发生了什么 ../image.jpg可以找到,为什么会导致空白不同?
只为你的兴趣:
<base href="http://example.com//" />与测试C<base href="http://example.com/ /" />是完全不同的。只有../image.jpg找到了<base href="a/" />仅找到 /images/image.jpg 最佳答案
base 的行为在 HTML 规范中解释:
The
baseelement allows authors to specify the document base URL for the purposes of resolving relative URLs.
如您的测试 A 所示,如果有多个 base 和 href,则 document base URL将是第一个。
Resolving relative URLs是这样完成的:
Apply the URL parser to url, with base as the base URL, with encoding as the encoding.
URL parsing算法在 URL 规范中定义。
它太复杂了,无法在这里详细解释。但基本上,情况是这样的:
/ 开头的相对 URL。/ 结尾,则最后一部分将是文件,而不是目录。./为当前目录../ 向上一个目录(可能“目录”和"file"不是 URL 中的正确术语)
一些例子:
http://example.com/images/a/./ 是 http://example.com/images/a/http://example.com/images/a/../ 是 http://example.com/images/http://example.com/images//./ 是 http://example.com/images//http://example.com/images//../ 是 http://example.com/images/http://example.com/images/./ 是 http://example.com/images/http://example.com/images/../ 是 http://example.com/请注意,在大多数情况下,// 类似于/。作为said by @poncha ,
Unless you're using some kind of URL rewriting (in which case the rewriting rules may be affected by the number of slashes), the uri maps to a path on disk, but in (most?) modern operating systems (Linux/Unix, Windows), multiple path separators in a row do not have any special meaning, so /path/to/foo and /path//to////foo would eventually map to the same file.
但是一般//不会变成//。
您可以使用以下代码段将相对 URL 列表解析为绝对 URL:
var bases = [
"http://example.com/images/",
"http://example.com/images",
"http://example.com/",
"http://example.com/images//",
"http://example.com/images/ /"
];
var urls = [
"/images/image.jpg",
"image.jpg",
"./image.jpg",
"images/image.jpg",
"/image.jpg",
"../image.jpg"
];
function newEl(type, contents) {
var el = document.createElement(type);
if(!contents) return el;
if(!(contents instanceof Array))
contents = [contents];
for(var i=0; i<contents.length; ++i)
if(typeof contents[i] == 'string')
el.appendChild(document.createTextNode(contents[i]))
else if(typeof contents[i] == 'object') // contents[i] instanceof Node
el.appendChild(contents[i])
return el;
}
function emoticon(str) {
return {
'http://example.com/images/image.jpg': 'good',
'http://example.com/images//image.jpg': 'neutral'
}[str] || 'bad';
}
var base = document.createElement('base'),
a = document.createElement('a'),
output = document.createElement('ul'),
head = document.getElementsByTagName('head')[0];
head.insertBefore(base, head.firstChild);
for(var i=0; i<bases.length; ++i) {
base.href = bases[i];
var test = newEl('li', [
'Test ' + (i+1) + ': ',
newEl('span', bases[i])
]);
test.className = 'test';
var testItems = newEl('ul');
testItems.className = 'test-items';
for(var j=0; j<urls.length; ++j) {
a.href = urls[j];
var absURL = a.cloneNode(false).href;
/* Stupid old IE requires cloning
https://stackoverflow.com/a/24437713/1529630 */
var testItem = newEl('li', [
newEl('span', urls[j]),
' → ',
newEl('span', absURL)
]);
testItem.className = 'test-item ' + emoticon(absURL);
testItems.appendChild(testItem);
}
test.appendChild(testItems);
output.appendChild(test);
}
document.body.appendChild(output);span {
background: #eef;
}
.test-items {
display: table;
border-spacing: .13em;
padding-left: 1.1em;
margin-bottom: .3em;
}
.test-item {
display: table-row;
position: relative;
list-style: none;
}
.test-item > span {
display: table-cell;
}
.test-item:before {
display: inline-block;
width: 1.1em;
height: 1.1em;
line-height: 1em;
text-align: center;
border-radius: 50%;
margin-right: .4em;
position: absolute;
left: -1.1em;
top: 0;
}
.good:before {
content: ':)';
background: #0f0;
}
.neutral:before {
content: ':|';
background: #ff0;
}
.bad:before {
content: ':(';
background: #f00;
}
你也可以玩这个片段:
var resolveURL = (function() {
var base = document.createElement('base'),
a = document.createElement('a'),
head = document.getElementsByTagName('head')[0];
return function(url, baseurl) {
if(base) {
base.href = baseurl;
head.insertBefore(base, head.firstChild);
}
a.href = url;
var abs = a.cloneNode(false).href;
/* Stupid old IE requires cloning
https://stackoverflow.com/a/24437713/1529630 */
if(base)
head.removeChild(base);
return abs;
};
})();
var base = document.getElementById('base'),
url = document.getElementById('url'),
abs = document.getElementById('absolute');
base.onpropertychange = url.onpropertychange = function() {
if (event.propertyName == "value")
update()
};
(base.oninput = url.oninput = update)();
function update() {
abs.value = resolveURL(url.value, base.value);
}label {
display: block;
margin: 1em 0;
}
input {
width: 100%;
}<label>
Base url:
<input id="base" value="http://example.com/images//foo////bar/baz"
placeholder="Enter your base url here" />
</label>
<label>
URL to be resolved:
<input id="url" value="./a/b/../c"
placeholder="Enter your URL here">
</label>
<label>
Resulting url:
<input id="absolute" readonly>
</label>
关于html - 如果 <base href...> 设置为双斜线会怎样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29122106/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request