Seif
Seif

Reputation: 749

Making an XHR request from AMP-HTML contact form to Laravel 5.4. 500 ERROR

I'm getting this error when making an ajax request from an AMP form to Laravel 5.4 controller.

This is the AMP-HTML form:

<form method="post"
    action-xhr="/mobile/help-post"
    target="_top"
    on="submit:msg.hide;submit-success:success-lightbox;submit-error:error-lightbox">

    <fieldset>
        <span>Your name</span>
        <input placeholder="Write here.." type="text" name="name" id="name" required>
    </fieldset>

    <fieldset>  
        <span>Your email</span>
        <input placeholder="Write here.." type="email" name="email" id="email" required>
    </fieldset>

    <fieldset>  
        <span>Your message</span>
        <textarea placeholder="Write here" name="message" id="email" required></textarea>
    </fieldset>

    <fieldset class="btn">  
        <input class="btn-primary" type="submit" value="Send Help Request »">
    </fieldset>

    <!--Error Messages-->
    <span visible-when-invalid="valueMissing" validation-for="name"></span>
    <span visible-when-invalid="valueMissing" validation-for="email"></span>
    <span visible-when-invalid="valueMissing" validation-for="message"></span>

    <span visible-when-invalid="typeMismatch" validation-for="name"></span>
    <span visible-when-invalid="typeMismatch" validation-for="email"></span>
    <span visible-when-invalid="typeMismatch" validation-for="message"></span>
    <!--End Error Messages-->

    <div submit-success>
        <template type="amp-mustache">
            Success! Sit tight and we'll get back to you soon!
        </template>
    </div>
    <div submit-error>
        <template type="amp-mustache">
            Oops!, We apologies something went wrong. Please try again later.
        </template>
    </div>
</form>

This is the controller:

public function postHelp(Request $request) {
    $this->validate($request, [
        'email' => 'required|email',
        'name' => 'required|min:3',
        'message' => 'required|min:10']);

    $data = array(
        'email' => $request->email,
        'name' => $request->subject,
        'bodyMessage' => $request->message
    );

    Mail::to('***@gmail.com')
    ->send($data);

    $response = array(
        'status' => 'success',
        'msg' => 'Setting created successfully',
    );
    return response($response, 200);
}

This is the route:

Route::prefix('mobile')->group(function(){
    Route::get('/help', 'PagesController@getHelp')->name('help');
    Route::post('/help-post', 'PagesController@postHelp')->name('help-post');
}

I receive this 500 error back from the server:

Type error: Argument 1 passed to Illuminate\Session\Middleware\StartSession::addCookieToResponse() must be an instance of Symfony\Component\HttpFoundation\Response, instance of Illuminate\Routing\Redirector given, called in C:\xampp\htdocs**\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php on line 72

I have added this global middle ware as required by AMP-HTML:

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class AddHeaders
{
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);
        $response->header("Access-Control-Allow-Origin", '*'); 
        $response->header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        $response->header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token");
        $response->header("Access-Control-Expose-Headers", "AMP-Access-Control-Allow-Source-Origin");
        $response->header("AMP-Access-Control-Allow-Source-Origin", 'http://localhost:8000');
        $response->header("Access-Control-Allow-Credentials", "true");

        return $response;
    }
}

As you can see in the last two lines in the error stack:

in StartSession.php (line 170)
at StartSession->addCookieToResponse(object(Redirector), object(Store))

It complains that addCookieToResponse receives a Redirector instead of a Response object.

This is the part in the framework (namespace Illuminate\Session\Middleware\StartSession.php) where addCookieToResponse is called - Please read my note in the code:

public function handle($request, Closure $next)
    {
        $this->sessionHandled = true;

        // If a session driver has been configured, we will need to start the session here
        // so that the data is ready for an application. Note that the Laravel sessions
        // do not make use of PHP "native" sessions in any way since they are crappy.
        if ($this->sessionConfigured()) {
            $request->setLaravelSession(
                $session = $this->startSession($request)
            );

            $this->collectGarbage($session);
        }

        $response = $next($request);

        // Again, if the session has been configured we will need to close out the session
        // so that the attributes may be persisted to some storage medium. We will also
        // add the session identifier cookie to the application response headers now.
        if ($this->sessionConfigured()) {
            $this->storeCurrentUrl($request, $session);

            $this->addCookieToResponse($response, $session);-->LOOK HERE: so is $response here a Redirector object ??????? But it's $response = $next($request); !!!!!!
        }

        return $response;
    }

I highly doubt that there's something in the framework. But, I can't tell where I returned a Redirector instead of a Response. It's plain simple sequence from the form to the route to the controller back to the form!

Upvotes: 0

Views: 1816

Answers (1)

Leo
Leo

Reputation: 7420

You forgot to add csrf_field()

<form method="post"
    action-xhr="/mobile/help-post"
    target="_top"
    on="submit:msg.hide;submit-success:success-lightbox;submit-error:error-lightbox">
      {{csrf_field()}}
    <fieldset>
        <span>Your name</span>
        <input placeholder="Write here.." type="text" name="name" id="name" required>
    </fieldset>

    <fieldset>  
        <span>Your email</span>
        <input placeholder="Write here.." type="email" name="email" id="email" required>
    </fieldset>

    <fieldset>  
        <span>Your message</span>
        <textarea placeholder="Write here" name="message" id="email" required></textarea>
    </fieldset>

    <fieldset class="btn">  
        <input class="btn-primary" type="submit" value="Send Help Request »">
    </fieldset>

    <!--Error Messages-->
    <span visible-when-invalid="valueMissing" validation-for="name"></span>
    <span visible-when-invalid="valueMissing" validation-for="email"></span>
    <span visible-when-invalid="valueMissing" validation-for="message"></span>

    <span visible-when-invalid="typeMismatch" validation-for="name"></span>
    <span visible-when-invalid="typeMismatch" validation-for="email"></span>
    <span visible-when-invalid="typeMismatch" validation-for="message"></span>
    <!--End Error Messages-->

    <div submit-success>
        <template type="amp-mustache">
            Success! Sit tight and we'll get back to you soon!
        </template>
    </div>
    <div submit-error>
        <template type="amp-mustache">
            Oops!, We apologies something went wrong. Please try again later.
        </template>
    </div>

Upvotes: 2

Related Questions