从本地文件加载新的 window 并访问它的内容

Loading a new window from local files and accessing it's contents

我正在设置一个本地网页,该网页在 HTML5 视频标签中显示视频。我只想能够从 PHP 请求进行数据库搜索并显示结果,我可以从中单击并显示我想要的视频。我遇到的问题是,从 "file:///" link 加载视频比从 "http://" link 加载视频快得多。服务器在 "HTTP" 模式下工作完美,但在 "file:///" 模式下没有任何工作,这是正常的,因为 PHP 代码仅在向服务器请求时在服务器端执行。

我花了一整天的时间尝试了很多东西。我更改了我的服务器以接受 CORS,我尝试 window.open,将引用存储在本地或全局变量中,但是一旦我退出我的 javascript 函数,我就丢失了它。我在一个从另一个函数调用的函数中尝试了 window.open,但无论我做什么,一旦我离开函数或函数完成后,window 引用就会丢失。由于我的浏览器用作我的主浏览器,我不想禁用 CORS 周围的安全性,但由于我网页的 link 来自 "file:///" 在同一台计算机上请求 "HTTP",CORS 块我想要一个我不能给的 HTTP 请求。

我已经完成了从另一个网页检索信息的所有搜索,但我总是被 "same domain" 问题困住。我尝试了 AJAX HTTPRequest,对于这个简单的问题,我没有更多的解决方案,它比预期的要复杂得多。最初的问题只是我的视频在 HTTP 模式下加载速度不够快(速度差异很大,对于 10 分钟的视频,我可以等待 5-10 秒来跳过它,而在 FILE:/// urls 中,它几乎是即时的,不用等待。1 小时的更长视频,我可以等待长达 20 和 30 秒,而在 file:/// 模式下,几乎是即时的。)而且我必须学习所有允许跨域的东西,但最终也没有成功.我想现在也许其他几个头比我有更好的想法。

#In my httpd.conf file from Apache
DocumentRoot "e:/mainwebfolder"
Alias "/lp" "d:/whatever"

//////////////////////////////////////
// index.php file that does not contain PHP contents
// window.location.href: file://d:/whatever/index.php
//////////////////////////////////////
<head>
  <script src="html/servcom.js" type="text/javascript"></script>
</head>
<video id="vplayer" width="1280" height="720" controls></video>
<div id="search-form">
  <input id="srch" name="srch" type="text">
  &nbsp;<button class="bbut" onclick="ServInfo('search-results','http://127.0.0.1/lp/html/db.php','mode=s','search-form');">Search</button>
</div>
<div id='search-results'></div>

<script>
  var dplay = document.getElementById("vplayer");
ShowVideo('MyVideo.mp4');
  function ShowVideo (vidUrl) {
    dplay = document.getElementById("vplayer");
    dplay.src = vidUrl;
    dplay.load;
  }
</script>

//////////////////////////////////////
// Now this is in my javascript file servcom.js
//////////////////////////////////////
var win_ref = -1;

function ServInfo(pop_field_id,web_page,params="",form_id="",exec_string = "") {

  var sparams = params;
  var swpage = web_page;
  var eobj = document.getElementById(pop_field_id);
  var moreparams = "";

  // If we entered extra parameters including form fields,
  // add the the "&" before the form field list
  if (sparams != "") {moreparams = "&";}

  // Get form field values if a form id is specified
  if (form_id != "") {
    var efrm = document.getElementById(form_id);
    sparams += moreparams+GetDivFields(form_id);
  }

  // Add the question mark if there is any parameters to pass
  if (sparams != "") {
    sparams = "?"+sparams;
    // Add recieving objects reference
    sparams += "&srco="+pop_field_id;
  }

  // If HTML element to populate does not exist, exit
  if (typeof(eobj) == "!undefined" || eobj == null) {return;}

  win_ref = window.open(swpage+sparams,"_blank");
//////////////////////////////////////
// right here win_ref will never be available once the code from this function has been finished executing although the variable is global. The problem starts here.
//////////////////////////////////////

  // Execute a string if a user defined one
  if (exec_string != "") {eval(exec_string);}
}

// Build a parameter string with div fields of type text, hidden or password
function GetDivFields(div_id) {

  var ediv = document.getElementById(div_id);
  var elem = ediv.children;
  var retval = "";
  var ssep = "";

  for (var i = 0; i < elem.length; i++) {
  if (elem[i].type == "text" || elem[i].type == "hidden" || elem[i].type == "password") {
    retval += ssep+elem[i].name+"="+pURL(elem[i].value);
    ssep = "&";
  }
  if (elem[i].type == "checkbox") {
    if (elem[i].checked == true) {
      retval += ssep+elem[i].name+"="+elem[i].value;
      ssep = "&";
    }
  }
}

return retval;

}
//////////////////////////////////////
// And this is a brief overview of my db.php page
//////////////////////////////////////
<?php // Search Database code ?>
<div id="output"></div>
<script>
  document.getElementById('output').innerHTML = "<?php echo $search_results; ?>";
  // I actually want to retrieve the info from this div element once it has been populated from the initial page that called window.open for this page. BUT again. window.opener becomes empty once my initial window.open script finishes.
</script>

访问我新加载的页面的 "output" div innerHTML 或通过本地 HTTP 以 "FILE:///".

的速度加载视频

好吧,我终于找到了解决办法。由于这仅供本地和演示使用,我可以绕过一些证券。基本上,做我们通常不会在网站上做的事情,但所有这一切都没有修改您的网络服务器配置或接触任何 .htaccess 文件。基本上,没有安全限制,只是一个普通的老黑客,不会对您的浏览器或服务器造成安全漏洞。

需注意:

  1. 存在 2 个不同的网站(因此 2 个不同的文件夹位于非常不同的位置),1 个用于开发和正式发布,一个用于内部 and/or 演示目的。

  2. 演示文稿文件夹中的每个文件都是本地文件。

  3. 没有 PHP 代码可以是 运行 来自 "file:///" link.

  4. 通过 PHP 访问 mysql 数据库,服务器在 Apach24

  5. 从 "file:///" link 本地读取视频比从 "http://" link

  6. 搜索需要在 MySQL 数据库中完成 "http://" link 并且结果需要显示在从 [=80= 打开的网页上] link.

  7. 无需更改浏览器的配置,因此禁用 CORS 不是解决方案。

  8. 由于安全原因或 CORS 绕过不接受 "file:///" links

    [,使用许多站点提出的方法绕过 cors 将不起作用=68=]

PHP 可以在服务器上写入文件,这是我决定绕过 CORS 的地方。由于 XML 通过 AJAX 的请求可以在同源域上完成,因此,纯粹在 javascript 中。如果存在不包含 PHP 代码且位于同一域 i/e "file:///" 上的文件,则可以毫无问题地读取内容。

所以我只需在 db.php 文件中执行以下操作:

$s_mode = "";
$s_text = "";
$sres = "";

if (isset($_REQUEST["srch"])) {$s_text=$_REQUEST["srch"];}
if (isset($_REQUEST["mode"])) {$s_mode=$_REQUEST["mode"];}

if ($s_mode == "s") {
    $sres = SearchDB($s_text);
    WriteFile("D:/whatever/my_path/dbres.html",$sres);
}

// Writes the contents of the search in a specified file
function WriteFile($faddress,$fcontents) {
    $ifile = fopen($faddress,"w");
    fwrite($ifile,$fcontents);
    fclose($ifile);
}

现在使用正常的 AJAX 请求,我做了两件事。我选择使用具有 "display:none" 样式的 iframe,以免看到另一个选项卡打开。

  1. 执行在执行我的 db.php 代码的 iframe 中打开 "cross-doamin" link 的实际请求。我基本上在我的 iframe 中打开“http://127.0.0.1/whatever/db.php?param1=data&parma2=data”。

  2. 完成搜索并获得结果后,我的 db.php 将保存一个 html 文件,其中包含我的 "file:///" 目录中的内容位置的路径因此:"D:/whatever/my_path/dbres.html".

我在 servcom.js 中添加了一个新功能。所以我的新文件的内容如下所示:

// Show page info in another page element or window with parameters (for local use only)
function ServInfoLocal(dest_frame,web_page,params="",form_id="") {
    var sparams = params;
    var swpage = web_page;
    var iweb = document.getElementById(dest_frame);
    var moreparams = "";

    // If we entered extra parameters including form fields,
    // add the the "&" before the form field list
    if (sparams != "") {moreparams = "&";}

    // Get form field values if a form id is specified
    if (form_id != "") {
        var efrm = document.getElementById(form_id);
        sparams += moreparams+GetDivFields(form_id);
    }

    // If destination frame does not exist, exit
    if (typeof(iweb) == "!undefined" || iweb == null)   {return;}

    // Add the question mark if there is any parameters to pass
    if (sparams != "") {sparams = "?"+sparams;}

    // Show results in iframe
    iweb.src = swpage+sparams;

}

// AJAX simple HTTP GET request
function ServInfo(pop_field_id,web_page,params="",form_id="",append_data_to_output = "",exec_string = "",dont_show_results = "") {

    var sparams = params;
    var swpage = web_page;
    var eobj = document.getElementById(pop_field_id);
    var moreparams = "";

    // If we entered extra parameters including form fields,
    // add the the "&" before the form field list
    if (sparams != "") {moreparams = "&";}

    // Get form field values if a form id is specified
    if (form_id != "") {
        var efrm = document.getElementById(form_id);
        sparams += moreparams+GetDivFields(form_id);
    }

    // If HTML element to populate does not exist, exit
    if (typeof(eobj) == "!undefined" || eobj == null)   {return;}

    if (window.XMLHttpRequest) {
        // IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    }
    else {
        // IE6-
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            // Do not show any results if requested
            if (dont_show_results == "") {
                if (append_data_to_output == "y") {
                    document.getElementById(pop_field_id).innerHTML += this.responseText;
                }
                if (append_data_to_output == "") {
                    document.getElementById(pop_field_id).innerHTML = this.responseText;
                }
            }
            // Execute a string if a user defined one
            if (exec_string != "") {
                eval(exec_string);
            }
        }
    };
    // Add the question mark if there is any parameters to pass
    if (sparams != "") {swpage += "?";}

    xmlhttp.open("GET",swpage+sparams,true);
    xmlhttp.send();

    }

// Build a parameter string with div fields of type text, hidden or password
function GetDivFields(div_id) {

    var ediv = document.getElementById(div_id);
    var elem = ediv.children;
    var retval = "";
    var ssep = "";

    for (var i = 0; i < elem.length; i++) {
        if (elem[i].type == "text" || elem[i].type == "hidden" || elem[i].type == "password") {
            retval += ssep+elem[i].name+"="+pURL(elem[i].value);
            ssep = "&";
        }
        if (elem[i].type == "checkbox") {
            if (elem[i].checked == true) {
                retval += ssep+elem[i].name+"="+elem[i].value;
                ssep = "&";
            }
        }
    }

    return retval;

}

现在,我的 dbres.html 文件将只包含 div 元素和我需要显示在我的 "file:///" 页面(搜索请求来自该页面)中的所有信息。所以我只是在我的页面中有这个:

<div id="search-form" style="color:white;font-weight:bold;">
    <input id="srch" name="srch" type="text">
    &nbsp;<button class="bbut" onclick="ServInfoLocal('iweb','http://127.0.0.1/whatever/html/db.php','mode=s','search-form');">Search</button>
    <button class="bbut" onclick="ServInfo('search-results','dbres.html');">Click here</button>
</div>

<div id="search-results">Results here</div>

<iframe id="iweb" style="display:none;" src=""></iframe>

现在我有 2 个按钮,一个用于搜索,一个用于显示我新创建的文件的结果。现在,我可以显示我的本地视频,这些视频将直接加载到带有 "file:///" 源的视频容器中,而无需通过 http。我会让我的结果自动显示,从现在开始我可以自己做。

因此,如果地球上的某个人希望能够直接从 Windows 资源管理器中的本地文件 运行 在 MySQL 数据库中进行跨域搜索,没有太多解决方案,实际上,我找到了 none 所以这里至少有一个适合需要此解决方案的人。

对于那些好奇的人,我的下一步是循环我的文件夹,直到我的 dbres 文件出现,使用另一个 js 函数。获取我的文件后,调用另一个 php 文件,该文件将破坏创建的文件,我将准备好从位于 "file:///" 位置的网页发出另一个数据库请求。