Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何捕获AJAX请求(SilverStripe 3.4)_Silverstripe - Fatal编程技术网

如何捕获AJAX请求(SilverStripe 3.4)

如何捕获AJAX请求(SilverStripe 3.4),silverstripe,Silverstripe,我有一个表单,它应用于整个站点的每个页面,需要异步发送,而不需要将用户带到任何地方 我想不出如何捕捉发送的数据。。。我之所以使用Page.php,是因为我假设它位于它所属的每个页面上;我在SilverStripe网站上浏览了ajax教程,但这并没有真正涵盖这个主题,只是正在开发的示例网站。我读了它,看了视频,还是不明白 我需要知道的是将数据发送到哪个URL(我假设它是任意的,因为页面适用于所有页面,对吗?)以及如何捕获请求… 目前,我已经准备好了发送信息的脚本,但不明白我需要在服务器端做什么 这

我有一个表单,它应用于整个站点的每个页面,需要异步发送,而不需要将用户带到任何地方

我想不出如何捕捉发送的数据。。。我之所以使用Page.php,是因为我假设它位于它所属的每个页面上;我在SilverStripe网站上浏览了ajax教程,但这并没有真正涵盖这个主题,只是正在开发的示例网站。我读了它,看了视频,还是不明白

我需要知道的是将数据发送到哪个URL(我假设它是任意的,因为页面适用于所有页面,对吗?)以及如何捕获请求…
目前,我已经准备好了发送信息的脚本,但不明白我需要在服务器端做什么

这是我在后端自动取款机里的东西,我能做些什么来让它工作呢

Page.php

 class Page_Controller extends ContentController {

    private static $allowed_actions = array(
        'flagDated'
    );

    public function flagDated(SS_HTTPRequest $request){

        echo $request;

        if($request->isAjax()){
            //
        }
    }

    public function init() {
        parent::init();
        Requirements::javascript('themes/three-two/js/flag-dated.js');
    }
 }

更新

我想我已经有些成功了。我发现重新安排我所拥有的东西会让我更接近我需要的地方。现在的问题是,
$request->isAjax()
失败,并且返回
basic return

我仍然不确定我做错了什么--我发现在请求末尾添加
?ajax=1
可以解决这个问题

 class Page extends SiteTree {

    // ...

    public static $allowed_actions = array(
        'flagDated'
    );

 }

 class Page_Controller extends ContentController {

    public function flagDated(SS_HttpRequest $request){

        if($request->isAjax()){
            return '$request';
        }

        return 'basic return';
    }

    public function init() {
        parent::init();
        Requirements::javascript('themes/three-two/js/flag-dated.js');
    }
 }
FireFox控制台返回
200
响应:基本返回


更新II

好的,我在服务器端接收数据,但在将数据导入
postVars
时遇到了一个小问题

因此,当我编写更新时,我开始得到
403
禁止
此处理程序上不允许执行“flagDated”操作。
返回。。。我没有改变任何与权限有关的事情,是什么原因造成的?是不是
$allowed\u actions
?因为自从我上次更新后它一直在工作<代码>PHP致命错误:对VirtualPage\u控制器的访问级别::$allowed\u操作必须是公共的(如在类页面\u控制器中)


嗯。。。我发现如果我将
中的
中的
更改为
public
,它会再次工作,我会得到一个
200
响应。。。这里有什么问题?为什么该页面会影响其他页面?

您将数据提交到表单“action”(表单元素上的属性)中。这是表单处理程序

我很久以前写了一篇要点来处理ajax表单提交()

下面是一个完整的示例,介绍如何设置一个基本表单,该表单接受AJAX和传统默认浏览器行为提交的内容(这是一个良好的实践):

将表单添加到控制器 首先,我们需要定义我们的形式;您的
Page\u控制器应如下所示:

class Page_Controller extends ContentController {

    /**
     * A list of "actions" (functions) that are allowed to be called from a URL
     *
     * @var array
     * @config
     */
    private static $allowed_actions = array(
        'Form',
        'complete',
    );

    /**
     * A method to return a Form object to display in a template and to accept form submissions
     *
     * @return Form
     */
    public function Form() {
        // include our javascript in the page to enable our AJAX behaviour
        Requirements::javascript('framework/thirdparty/jquery/jquery.js');
        Requirements::javascript('mysite/javascript/ajaxforms.js');
        //create the fields we want
        $fields = FieldList::create(
            TextField::create('Name'),
            EmailField::create('Email'),
            TextareaField::create('Message')
        );
        //create the button(s) we want
        $buttons = FieldList::create(
            FormAction::create('doForm', 'Send')
        );
        //add a validator to make sure the fields are submitted with values
        $validator = RequiredFields::create(array(
            'Name',
            'Email',
            'Message',
        ));
        //construct the Form
        $form = Form::create(
            $this,
            __FUNCTION__,
            $fields,
            $buttons,
            $validator
        );

        return $form;
    }

    /**
     * The form handler, this runs after a form submission has been successfully validated
     *
     * @param $data array RAW form submission data - don't use
     * @param $form Form The form object, populated with data
     * @param $request SS_HTTPRequest The current request object
     */
    public function doForm($data, $form, $request) {
        // discard the default $data because it is raw submitted data
        $data = $form->getData();

        // Do something with the data (eg: email it, save it to the DB, etc

        // send the user back to the "complete" action
        return $this->redirect($this->Link('complete'));
    }

    /**
     * The "complete" action to send users to upon successful submission of the Form.
     *
     * @param $request SS_HTTPRequest The current request object
     * @return string The rendered response
     */
    public function complete($request) {
        //if the request is an ajax request, then only render the include
        if ($request->isAjax()) {
            return $this->renderWith('Form_complete');
        }
        //otherwise, render the full HTML response
        return $this->renderWith(array(
            'Page_complete',
            'Page',
        ));
    }

}

将这些函数添加到Page Orthor 会使它们在<>强>所有< /强>页类型上可用——这可能不需要,并且您应该考虑是否创建一个新的页面类型(如CONTACTPAGE)更适合于在

上具有这种形式? 在这里,我们定义了以下方法:

  • 创建
    表单
  • 表单处理程序(要将提交的内容保存或发送到某处,在
    表单
    成功验证其数据后运行)
  • 一个
    完成
    操作,用户在成功完成表单提交后将发送到该操作
定制模板以方便内容替换 接下来,我们需要设置模板-修改布局/Page.ss文件:

<% include SideBar %>
<div class="content-container unit size3of4 lastUnit">
    <article>
        <h1>$Title</h1>
        <div class="content">$Content</div>
    </article>
    <div class="form-holder">
        $Form
    </div>
        $CommentsForm
</div>
接下来创建
include/Form_complete
include-使用include很重要,这样我们就可以呈现页面的这一部分来响应AJAX请求:

<h2>Thanks, we've received your form submission!</h2>
<p>We'll be in touch as soon as we can.</p>
这个javascript将使用AJAX提交表单,完成后将淡出表单,替换为响应,然后淡入

对于高级用户: 在本例中,您站点上的所有表单都将“ajaxified”,这可能是可以接受的,但有时您需要对此进行一些控制(例如,搜索表单不会像这样工作)。相反,您可以稍微修改代码,以便只查找具有特定类的表单

修改控制器
页面上的
表单
方法,如下所示:

public function Form() {
    ...
    $form->addExtraClass('js-ajax-form');
    return $form;
}
对javascript进行如下修改:

$(window).on('submit', '.js-ajax-form', function(e) {
    ...
})(jQuery);

现在只有类为js ajax form的表单才会以这种方式工作。

我已经设法让它工作。
这是我的解决方案,任何人都可以看到如何使用SilverStripe实现ajax,而不管用例是什么


HTML
非常基本,只是向用户提供一些字段来输入内容

 <div class="flag-dated-container hidden">

     <div class="modal-window">

         <div class="header">
             <h1>Flagging $Title</h1>
             <div class="close" data-action="close" title="Close">X</div>
         </div><!-- . header -->

         <form>
             <input type="text" placeholder="This content is..." />
             <textarea placeholder="Explain the issue in full detail..."></textarea>
         </form>

         <div class="buttons">
             <div data-action="close">Cancel</div>
             <div data-action="send">Send</div>
         </div><!-- . buttons -->

     </div><!-- . modal-window -->

 </div><!-- . flag-dated -->
PHP
这是我遇到最多麻烦的部分。
$allowed\u actions
需要位于
控制器中,并设置为
专用
。我在JS脚本中设置的
标题
正文
是使用
$request->postVars('myVar')中相同的变量进行访问的


我不久前写了这个要点是为了帮助你:不确定,但也许我提供的答案有帮助?它使用基于AJAX的表单提交。基本上,您只需编写一个常规表单和提交处理程序,然后通过JS/AJAX而不是普通表单提交来提交表单。在后端没有太多的变化…这看起来非常像我需要的!我已经添加了我目前拥有的代码,这就是我所能做的,接下来我需要做什么?只是想澄清一下,我遇到的问题不是ajax方面,而是如何在框架中接收数据。旁注:不管怎样,谢谢你的链接,它有文档吗?或者这是使用它所需要的全部注释吗?没有其他文档。你能链接到你一直在关注的视频和文档吗?当然。这是主要的一个,然后几乎任何搜索结果哟
$(window).on('submit', '.js-ajax-form', function(e) {
    ...
})(jQuery);
 <div class="flag-dated-container hidden">

     <div class="modal-window">

         <div class="header">
             <h1>Flagging $Title</h1>
             <div class="close" data-action="close" title="Close">X</div>
         </div><!-- . header -->

         <form>
             <input type="text" placeholder="This content is..." />
             <textarea placeholder="Explain the issue in full detail..."></textarea>
         </form>

         <div class="buttons">
             <div data-action="close">Cancel</div>
             <div data-action="send">Send</div>
         </div><!-- . buttons -->

     </div><!-- . modal-window -->

 </div><!-- . flag-dated -->
 var container = document.getElementsByClassName('flag-dated-container')[0];

 // Interaction functionality
 container.addEventListener('click', function(e){

     var target = e.target,
         userInput = container.querySelectorAll('input, textarea');

     if(target.dataset.action === 'send'){

         /*
             My function in the controller is called 'flagDated'
             so that's what I append to the end of the URL
             and the ?ajax=1 is to ensure it passes the isAjax() check
             in the controller
         */
         var r = new XMLHttpRequest(),
             url = window.location + 'flagDated?ajax=1',
             data = '';

         // Create the param to send
         data = 'title=' + encodeURIComponent(userInput[0].value);
         data += '&body=' + encodeURIComponent(userInput[1].value);

         r.onreadystatechange = function(){

             if(r.readyState === 4 && r.status === 200){
                 // Success, do something
             }
             else if(r.readyState !== 4 && (r.status === 400 || r.status === 500)){
                 // failed
             }
         }
         r.open('POST', url); // We use the current URL because it doesn't matter what the target is
         r.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
         r.send(data);
     }
 });
 class Page_Controller extends ContentController {

     private static $allowed_actions = array(
         'flagDated'
     );

     public function flagDated(SS_HttpRequest $request){

         if($request->isAjax() && $request->isPost()){

             $title = $request->postVar('title');
             $body = $request->postVar('body');

             $email = new Email(
                 'from@email.com',
                 'to@email.com',
                 'Flagged as Dated: ' . $title,
                 $body
             );

             $email->send();
         }
         else
             // Not ajax or post, do something else.
     }

     public function init() {
         parent::init();
         Requirements::javascript('themes/three-two/js/flag-dated.js');
     }
 }