我理解这种安全风险以及为什么会出现这样的错误:
Uncaught DOMException: Blocked a frame with origin
"http://myurl.com" from accessing a cross-origin frame.
所以我想知道我是否有安全的方法来做这件事。
我们公司有两个网站内部 - 我的,另一个不的网站存在于同一个网域。
在我的页面中,我有兴趣以允许我从该页面访问ID元素的方式加载第二页,提取这些ID元素包含的数据,并将该数据返回到我的页面,以便我可以显示它给我的用户。我没有API从第二个来源获取此数据。最终,我喜欢它,如果有一种方法可以让我将数据输入到源页面,但是一般来说注射和攻击的风险很大,我怀疑它有什么办法可以我这样做,即使我的意图不是恶意的。
我尝试了一些事情:
/* Literally load the page within my own and pull data once it's loaded */
$('#test').load('url.com/site2');
/* load the second page as a variable, then try to access an id on
that page through the variable */
var win = window.open('url.com/site2');
var test = win.getElementByID('#id_element_i_want_to_pull');
/* I can do something using PHP, but this just loads the page, but doesn't allow
me to access any of the ID elements on that page which
doesn't really help me: */
$temp = file_get_contents('url.com/site2');
有什么方法可以解决这个问题吗?我无法访问第二台服务器上的代码,因此我不会(可能)在那里放置任何可以授予我访问权限的代码,如果需要的话。如果这是唯一的方法,我至少想知道它,并知道如果可能的话,这种类型的请求是如何完成的。
答案 0 :(得分:1)
我认为你将它加载到服务器上是正确的轨道,你只需要将它解析为可用于通过id获取内容的东西。自从我在PHP中做了很多工作以来已经有一段时间了,但您应该能够使用DOMDocument类来完成这项工作。基本上你加载文本,把它扔进其中一个人,然后通过他们的id得到元素。
答案 1 :(得分:1)
如果它是您无法直接访问的网站,则听起来您可以做一些DOM" hoovering"或者"刮擦"使用已经提到的DOMDocument类。
使用DOMDocument,您可以获取整个页面的内容,然后根据您要查找的标记/属性对其进行过滤。我在过去曾在PHP7中写过类似的内容,这可能有所帮助:
class HooverDom {
public $content;
public static function checkContentUrl($url) {
if (stripos($url, 'http') !== 0) {
return 'http://' . $url;
}
return $url;
}
public function getContent($url) {
if (!$this->content) {
$url = self::checkContentUrl($url);
if ($url) {
$this->content = new \DOMDocument( '1.0', 'utf-8' );
$this->content->preserveWhiteSpace = false;
// suppress warnings from invalid code
@$this->content->loadHTMLFile($url);
}
}
return $this->content;
}
/**
* @param $url
* @param $tag
*
* @return array
* Extract tags that are of interest
*/
public function getTags($url, $tag) {
$count = 0;
$result = array();
$url = self::checkContentUrl($url);
if (!$url) return false;
$elements = $this->getContent($url)->getElementsByTagName($tag);
foreach ($elements as $node) {
$result[$count]['value'] = trim(preg_replace('/\s+/', ' ', $node->nodeValue));
if ($node->hasAttributes()) {
foreach ($node->attributes as $name => $attr) {
$result[$count]['attributes'][$name] = $attr->value;
}
}
$count++;
}
return $result;
}
/**
* @param $url
* @param $attr
* @param null [$domain]
*
* @return array
* Extract specific attributes rather than tags. Get all tags with *
* and get their attributes. Optional $domain value keeps all results
* within supplied domain name
*/
public function getAttributes($url, $attr, $domain = null) {
$result = array();
$elements = $this->getContent($url)->getElementsByTagName('*');
foreach ($elements as $node) {
if ($node->hasAttribute($attr)) {
$value = $node->getAttribute($attr);
if ($domain) {
if (stripos($value, $domain) !== FALSE) {
$result[] = trim($value);
}
} else {
$result[] = trim($value);
}
}
}
return $result;
}
}
define('DEFAULT_URL', 'https://developer.mozilla.org/en-US');
define('DEFAULT_TAG', 'div');
$vac = new HooverDom();
$url = strip_tags($_GET['url'] ?? DEFAULT_URL);
$tag = strip_tags($_GET['tag'] ?? DEFAULT_TAG);
echo 'Dump of tags: ' . PHP_EOL;
var_dump($vac->getTags($url, $tag));
这将获取页面上的所有链接并为您列出一个列表。这样就可以使用一些结构来代替file_get_contents()中的大量字符串。
使用https://developer.mozilla.org/en-US/作为示例,输出看起来像这样:
array (size=56)
0 =>
array (size=2)
'value' => string 'Mozilla is working on a new program for developers and other web builders like you. Help shape that program by taking our 10 minute survey: https://googl/forms/Ync2VuTWwAkQFvJx2' (length=178)
'attributes' =>
array (size=1)
'class' => string 'global-notice' (length=13)
1 =>
array (size=2)
'value' => string 'Mozilla is working on a new program for developers and other web builders like you. Help shape that program by taking our 10 minute survey: ' (length=178)
'attributes' =>
array (size=1)
'class' => string 'wrap center' (length=11)
..........
对于某些格式化错误感到抱歉,如果您需要澄清任何内容,请与我们联系。您可以遍历结果并隔离您要查找的特定元素ID /类/任何其他属性,并在" value"中获取内容。
注意NULL合并运算符(??)只有在PHP 7中才能运行5。