3

I have a route in my web.php that returns a view:

Route::get('/', function () {
    return view('welcome');
});

welcome is default Laravel view welcome.blade.php.

I have Middleware called AlwaysReturnJson and it contains:

<?php

namespace App\Http\Middleware;

use Closure;

class AlwaysReturnJson
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        $request->headers->set('Accept', 'application/json');
        return $next($request);
    }
}

I set up this middleware in Kernel.php as global middleware:

 protected $middleware = [
        \App\Http\Middleware\AlwaysReturnJson::class
    ];

What I expect is to get plain text/json of welcome file in my browser when I navigate to given route but I always get it as html and it render page properly. I checked it, it applies middleware on every request so that is not a problem. Why is this happening and shouldn't it convert that view to a plain text? Am I doing something wrong?

5
  • @AngadDubey no controller here. OP use closure to return view Commented Jan 14, 2020 at 16:14
  • try returning the view as json response return response()->json([ 'welcome' => view('welcome') ]); Commented Jan 14, 2020 at 16:16
  • 1
    @N.Dockic I'm trying use your way and success. I think it's not Laravel issue but webserver. Commented Jan 14, 2020 at 16:19
  • You are setting an Accept header, this is more like saying: "Always accept json". Commented Jan 14, 2020 at 16:27
  • @WahyuKristianto could you maybe give me direction about what problem could be with server? Commented Jan 15, 2020 at 10:18

2 Answers 2

4

If you want to set a header for your response you can do this:

namespace App\Http\Middleware;

use Closure;

class AlwaysReturnJson
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        $response->headers->set('Content-Type', 'application/json');

        return $response;
    }
}

If you want to force return valid json content use this middleware instead:

namespace App\Http\Middleware;

use Closure;

class AlwaysReturnJson
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        return response()->json($response->getContent());
    }
}

See Laravel docs about after middleware for more info.

You can alternatively return json response on your controller without any middleware needed:

Route::get('/', function () {
    return response()->json(
        view('welcome')->render()
    );
});
Sign up to request clarification or add additional context in comments.

2 Comments

Your answer is basically correct, I will mark it as accepted answer but have you tried example that I tried like this: $request->headers->set('Accept', 'application/json'); ? Does it return always json for you?
@N.Djokic my first answer just sets Content-Type header (not Accept). However I've updated my answer and added a code to force your response to be a valid json.
2

You may want to use laravel After middleware (the middleware would perform its task after the request is handled by the application) and then set the content-type of response.

<?php

namespace App\Http\Middleware;

use Closure;

class AfterAlwaysReturnJson
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        return $response->header('Content-Type', 'application/json');
    }
}

3 Comments

Thanks for answer. Have you tried my example code? Did it return json response?
I will give it a try and go back to you
I gave it a try , and YES your code works fine for me (tested on Laravel 5.7)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.