如何使用ajax将js变量发送到插件控制器?

时间:2016-10-21 01:13:15

标签: octobercms

我试图创建一个跟踪网站访问的非常简单的插件。我需要使用JS document.referrer获取页面引用者,将其传递给变量,并将该变量发送到插件控制器或组件,因此我可以将其存储在数据库中。我已经挣扎了好几天......尝试了我在Google上发现的一切......没有任何作用。请帮忙

使用vanilla JS和PHP的脚本非常容易实现。问题是将它整合到OctoberCMS中:(

// js
(function(){

function makeXHRRequest( url, callback, method, dataType ) {
  if(!window.XMLHttpRequest ) {
    return null;
  }
  var req = new XMLHttpRequest();
  method = method || 'GET';
  dataType = dataType || 'text/plain';
  req.open( method, url );
  req.setRequestHeader('Content-Type', dataType);

  req.onreadystatechange = function() {
    if( req.readyState === 4 ) { 
      if( req.status === 200 ) {
        callback.success(req);
      }
      else {
         callback.failure(req);
      }
    }
  }
  req.send(); 
  return req; 
}

// current page url
function getCurrentPage(){
    var urlPath = window.location.pathname;
    var domain  = window.location.hostname;
    var hostName;
    if (urlPath === '/'){
        hostName = urlPath.replace(urlPath, domain);
        return hostName;
    }
    else {
       return urlPath;
    }
}

// page referrer
function getPageReferrer(){
  return document.referrer;
}

function RequestPageInfo() {
  var pageReferrer = getPageReferrer();
  var currentPage  = getCurrentPage();

  var queryVars = 'current_page='+currentPage+'&page_referrer='+pageReferrer;

  var callback = {
      success: function(req) {
       document.getElementById('page-result').innerHTML = req.responseText;
      },
      failure: function(req) {
       document.getElementById('page-result').innerHTML = 'An error has occurred.';
      }
  }

  // request data
  makeXHRRequest('tvisitor.php?'+queryVars, callback, 'POST', 'application/json' );
}

window.onload = function() {
  RequestPageInfo();
};

})();

// visitor.php
// get ajax requested page url vars
$referrerPage = isset($_GET['page_referrer']) ? $_GET['page_referrer'] : "";
$PageUrl  = isset($_GET['current_page']) ?  $_GET['current_page'] : "";

1 个答案:

答案 0 :(得分:3)

免责声明:)

对于你想拥有的东西,你实际上根本不需要AJAX或任何javascript。当前页面url和referer信息都可以在服务器端php代码中访问(OctoberCMS也方便helper functions)。并且数据库存储也明显在那里处理。

但是主要问题实际上是如何通过要在那里处理从前端js到服务器端的变量,通过AJAX framework这里有一个解释。

十月的基本AJAX用法

您需要的最基本的成分是AJAX handler。您可以在代码部分的任何适当模板中定义AJAX处理程序:页面,部分(也包括组件部分),布局。

所有这些类型的10月模板分为多达三个部分:

# config section
# page variables and stuff can be set up here
title = "Hello"
==
<?php // code section
function thisAndThat()
{
    return "whatever";
}
?>
==
{# twig markup section #}
<h1>{{this.page.title}}</h1>
<p>You can use twig here.</p>

AJAX处理程序应遵循命名约定onThisAndThat。否则,就无法通过框架调用它们。

通过POST方法发送参数。所以你会在你的处理程序中使用它们,如下所示:

function onTrackVisit()
{
    $referer=post('referer'); // assuming the 'referer' and 'page' variables have been sent as POST parameters
    $page=post('page');       // post(' ... ') is just a helper function for $_POST[' ... ']
    doStuffWith($page, $referer); // to store them in the database ...
}

如何使用JavaScript

中的参数调用AJAX处理程序

好的,那么现在如何调用AJAX处理程序?

TLDR版本(有关我建议RTFM :)的进一步详情)

你可以做到

$.request("onTrackVisit", {data: {page: getCurrentPage(), referrer: getPageReferrer()}});

在模板标记部分中包含的javascript中,其中包含您在示例中定义的函数。现在,这些变量通过AJAX请求作为POST参数发送到服务器端的onTrackVisit()处理程序。

(将你的javascript置于其间的一种常见的干净方式

{%put scripts%}
<script> ... </script>
{%endput%}

这样它就会附加在你布局中的{% scripts %}占位符上(如果存在的话);或者,如果要构建插件组件,则可以添加一行

$this->addJs("path/to/your/script.js"); //(relative to the plugin root dir.)

在组件类的onRun()方法中(在{{your_plugin}}/components/VisitTracker.php或其他任何内容中)。)

构建插件和处理数据库内容的组件。

所以现在,为了处理插件和组件脚手架并处理数据库的东西,我之前的回答可能仍然有用。可能有太多细节。但我认为你可以忍受它。 :-P

您需要通过AJAX发送页面和引用来以您想要的方式进行更改,以便将下面的onRun方法重命名为onTrackVisit或其他内容,替换

    $thisVisit.page = request()->url();
    $thisVisit.referer = request()->header('referer');

    $thisVisit.page = post('page');
    $thisVisit.referer = post('referer');

并在您的组件的默认模板中添加一些代码,以使用您的javascript中所需的onTrackVisitpage数据参数进行refer(r)er AJAX调用。

这个答案解释了如何使用数据&#34; page&#34;创建一个带有用于记录页面访问的组件的插件。 (url)和&#34; referer&#34;将存储在相应的专用数据库表中。

虽然很明显你已经创建了一些你正在摆弄的插件,但我会从头开始,所以每一步都是合乎逻辑且易于理解的。我为这里或那里的某些背景下的夸张细节和冗长的解释道歉。

首先创建一个具有一些合理名称的基本插件(脚手架):

php artisan create:plugin YourNameSpace.VisitTracker

这将只创建目录plugins/yournamespace/visittracker和文件plugins/yournamespace/visittracker/Plugin.php(主插件文件;用于注册所有插件的组件,扩展等的代码)和{{ 1}}(版本信息文件;数据库迁移信息在这里)。

由于您希望在数据库中存储访问数据,因此您需要一个数据库模型(带有相应的数据库表)。

我假设您只需要一张名为&#34; visit&#34;。

的单一记录表
plugins/yournamespace/visittracker/updates/version.yaml

此命令创建一个名为&#34;访问&#34;的新基本模型类。没有任何有趣的属性,以及用于创建相应数据库表的迁移文件。

现在正在php artisan create:model YourNameSpace.VisitTracker Visit 中定义访问模型类,并在plugins/yournamespace/visittracker/models/Visit.php

中定义迁移文件

您不需要更改模型类定义文件中的任何内容。该模型将使用具有由迁移文件创建的相应名称的数据库表。需要在某个时刻运行迁移文件才能实际创建数据库表。为了使这种情况有序发生,您必须更改plugins/yournamespace/visittracker/updates/create_visits_table.php以在最新版本中包含迁移文件,如下所示:

<强>插件/ yournamespace / visittracker /更新/ version.yaml

plugins/yournamespace/visittracker/updates/version.yaml

这告诉octo,安装版本1.0.1(在这种情况下是第一个版本),应该运行迁移文件1.0.1: - First version of VisitTracker - create_visits_table.php 来更新数据库。

但首先你还需要稍微调整它以使其适合你的需要。

修改迁移文件中的create_visits_table.php功能(在up()BEGIN INSERT之间添加代码;评论只是解释一下) -

plugins / yournamespace / visittracker / updates / create_visits_table.php

END INSERT

现在,您可以通过以下命令从头开始运行所有迁移文件,告诉october(重新)创建所有插件的数据库表:

public function up()
{
    Schema::create('yournamespace_visittracker_visits', function(Blueprint $table) {
        $table->engine = 'InnoDB';
        $table->increments('id'); 

        /*
         * BEGIN INSERT
         *
         * your actual data columns
         */

        // include columns for page and refer(r)er:
        $table->string('page');

        // see http://english.stackexchange.com/questions/42630/referer-or-referrer/42636        
        $table->string('referer')

        /*
         * END INSERT
         */

        $table->timestamps();
    });
}

好的,现在到了前端。

您需要创建组件以将代码放入进行跟踪。同样,有一个工匠命令为此创建脚手架。让我们调用组件&#34; VisitTracker&#34;,就像插件本身一样:

php artisan plugin:refresh YourNamespace.VisitTracker

这为名为&#34; VisitTracker&#34;。

的组件创建了基本的脚手架

由于您的组件不应该做任何明显的操作,您应该将默认模板php artisan create:component YourNamespace.VisitTracker VisitTracker 清空,并且所有操作都将在组件的onRun()函数中进行,您定义如下,确保包括

plugins / yournamespace / visittracker / components / VisitTracker.php

plugins/yournamespace/visittracker/components/visittracker/default.htm

在文件的开头

plugins / yournamespace / visittracker / components / VisitTracker.php

use TestCase\VisitTracker\Models\Visit as VisitModel;

最后,您仍然需要在Plugin.php文件的public function onRun() { $thisVisit = new VisitModel(); $thisVisit.page = request()->url(); $thisVisit.referer = request()->header('referer'); $thisVisit->save(); } 函数中包含您的组件,以便它可以在CMS页面中使用。在Plugin类中的registerComponents()中(函数已经存在,你只需要正确填充它)

插件/ yournamespace / visittracker / Plugin.php 中的

plugins/yournamespace/visittracker/Plugin.php

希望这会以某种方式帮助你。非常欢迎关于清理或澄清的评论中的后续问题。

(如果你想为OctoberCMS建立一个专门的stackechange社区,请支持octobercms.stackexchange proposal。一旦达到目标,我将删除这条消息 - 承诺: ))