Skip to content

Commit d12312c

Browse files
authored
Inject data on every request, not just store (#1668)
* Inject data on every request, not just store * Do not add header when injecting * Add servertiming back * Tweak isJson * Tweak tests for injecting headers
1 parent 113cce2 commit d12312c

File tree

4 files changed

+66
-43
lines changed

4 files changed

+66
-43
lines changed

src/LaravelDebugbar.php

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -796,63 +796,57 @@ public function modifyResponse(Request $request, Response $response)
796796
$this->addClockworkHeaders($response);
797797
}
798798

799+
try {
800+
if ($this->hasCollector('views') && $response->headers->has('X-Inertia')) {
801+
$content = $response->getContent();
802+
803+
if (is_string($content)) {
804+
$content = json_decode($content, true);
805+
}
806+
807+
if (is_array($content)) {
808+
$this['views']->addInertiaAjaxView($content);
809+
}
810+
}
811+
} catch (Exception $e) {
812+
}
813+
814+
if ($app['config']->get('debugbar.add_ajax_timing', false)) {
815+
$this->addServerTimingHeaders($response);
816+
}
817+
799818
if ($response->isRedirection()) {
800819
try {
801820
$this->stackData();
802821
} catch (Exception $e) {
803822
$app['log']->error('Debugbar exception: ' . $e->getMessage());
804823
}
805-
} elseif (
806-
$this->isJsonRequest($request) &&
807-
$app['config']->get('debugbar.capture_ajax', true)
808-
) {
809-
try {
810-
if ($this->hasCollector('views') && $response->headers->has('X-Inertia')) {
811-
$content = $response->getContent();
812824

813-
if (is_string($content)) {
814-
$content = json_decode($content, true);
815-
}
825+
return $response;
826+
}
816827

817-
if (is_array($content)) {
818-
$this['views']->addInertiaAjaxView($content);
819-
}
820-
}
821-
} catch (Exception $e) {
822-
}
823-
try {
824-
$this->sendDataInHeaders(true);
828+
try {
829+
// Collect + store data, only inject the ID in theheaders
830+
$this->sendDataInHeaders(true);
831+
} catch (Exception $e) {
832+
$app['log']->error('Debugbar exception: ' . $e->getMessage());
833+
}
825834

826-
if ($app['config']->get('debugbar.add_ajax_timing', false)) {
827-
$this->addServerTimingHeaders($response);
828-
}
829-
} catch (Exception $e) {
830-
$app['log']->error('Debugbar exception: ' . $e->getMessage());
831-
}
832-
} elseif (
833-
!$app['config']->get('debugbar.inject', true) ||
834-
($response->headers->has('Content-Type') &&
835-
strpos($response->headers->get('Content-Type'), 'html') === false) ||
836-
$request->getRequestFormat() !== 'html' ||
837-
$response->getContent() === false ||
838-
$this->isJsonRequest($request)
835+
// Check if it's safe to inject the Debugbar
836+
if (
837+
$app['config']->get('debugbar.inject', true)
838+
&& str_contains($response->headers->get('Content-Type', 'text/html'), 'html')
839+
&& !$this->isJsonRequest($request, $response)
840+
&& $response->getContent() !== false
841+
&& in_array($request->getRequestFormat(), [null, 'html'], true)
839842
) {
840-
try {
841-
// Just collect + store data, don't inject it.
842-
$this->collect();
843-
} catch (Exception $e) {
844-
$app['log']->error('Debugbar exception: ' . $e->getMessage());
845-
}
846-
} else {
847843
try {
848844
$this->injectDebugbar($response);
849845
} catch (Exception $e) {
850846
$app['log']->error('Debugbar exception: ' . $e->getMessage());
851847
}
852848
}
853849

854-
855-
856850
return $response;
857851
}
858852

@@ -889,9 +883,10 @@ protected function isDebugbarRequest()
889883

890884
/**
891885
* @param \Symfony\Component\HttpFoundation\Request $request
886+
* @param \Symfony\Component\HttpFoundation\Response $response
892887
* @return bool
893888
*/
894-
protected function isJsonRequest(Request $request)
889+
protected function isJsonRequest(Request $request, Response $response)
895890
{
896891
// If XmlHttpRequest, Live or HTMX, return true
897892
if (
@@ -904,7 +899,17 @@ protected function isJsonRequest(Request $request)
904899

905900
// Check if the request wants Json
906901
$acceptable = $request->getAcceptableContentTypes();
907-
return (isset($acceptable[0]) && $acceptable[0] == 'application/json');
902+
if (isset($acceptable[0]) && in_array($acceptable[0], ['application/json', 'application/javascript'], true)) {
903+
return true;
904+
}
905+
906+
// Check if content looks like JSON without actually validating
907+
$content = $response->getContent();
908+
if ($content !== false && in_array($content[0], ['{', '['], true)) {
909+
return true;
910+
}
911+
912+
return false;
908913
}
909914

910915
/**

tests/DebugbarTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public function testItInjectsOnPlainText()
3535

3636
$this->assertTrue(Str::contains($crawler->content(), 'debugbar'));
3737
$this->assertEquals(200, $crawler->getStatusCode());
38+
$this->assertNotEmpty($crawler->headers->get('phpdebugbar-id'));
3839
}
3940

4041
public function testItInjectsOnHtml()
@@ -43,6 +44,7 @@ public function testItInjectsOnHtml()
4344

4445
$this->assertTrue(Str::contains($crawler->content(), 'debugbar'));
4546
$this->assertEquals(200, $crawler->getStatusCode());
47+
$this->assertNotEmpty($crawler->headers->get('phpdebugbar-id'));
4648
}
4749

4850
public function testItDoesntInjectOnJson()
@@ -51,6 +53,16 @@ public function testItDoesntInjectOnJson()
5153

5254
$this->assertFalse(Str::contains($crawler->content(), 'debugbar'));
5355
$this->assertEquals(200, $crawler->getStatusCode());
56+
$this->assertNotEmpty($crawler->headers->get('phpdebugbar-id'));
57+
}
58+
59+
public function testItDoesntInjectOnJsonLookingString()
60+
{
61+
$crawler = $this->call('GET', 'web/fakejson');
62+
63+
$this->assertFalse(Str::contains($crawler->content(), 'debugbar'));
64+
$this->assertEquals(200, $crawler->getStatusCode());
65+
$this->assertNotEmpty($crawler->headers->get('phpdebugbar-id'));
5466
}
5567

5668
public function testItDoesntInjectsOnHxRequestWithHxTarget()
@@ -62,6 +74,7 @@ public function testItDoesntInjectsOnHxRequestWithHxTarget()
6274

6375
$this->assertFalse(Str::contains($crawler->content(), 'debugbar'));
6476
$this->assertEquals(200, $crawler->getStatusCode());
77+
$this->assertNotEmpty($crawler->headers->get('phpdebugbar-id'));
6578
}
6679

6780
public function testItInjectsOnHxRequestWithoutHxTarget()
@@ -72,5 +85,6 @@ public function testItInjectsOnHxRequestWithoutHxTarget()
7285

7386
$this->assertTrue(Str::contains($crawler->content(), 'debugbar'));
7487
$this->assertEquals(200, $crawler->getStatusCode());
88+
$this->assertNotEmpty($crawler->headers->get('phpdebugbar-id'));
7589
}
7690
}

tests/TestCase.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ protected function addWebRoutes(Router $router)
6666
return '<html><head></head><body>Pong</body></html>';
6767
});
6868

69+
$router->get('web/fakejson', function () {
70+
return '{"foo":"bar"}';
71+
});
72+
6973
$router->get('web/show', [ MockController::class, 'show' ]);
7074

7175
$router->get('web/view', MockViewComponent::class);

tests/resources/views/ajax.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<script>
88
async function loadAjax() {
99
try {
10-
const response = await fetch('/api/ping', {headers: {'X-Requested-With': 'XMLHttpRequest'}});
10+
const response = await fetch('/api/ping');
1111
if (!response.ok) {
1212
throw new Error(`Response status: ${response.status}`);
1313
}

0 commit comments

Comments
 (0)