Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

aarontharker's avatar

Post request sent via axios not being read in Laravel

I'm sending my post request like so

axios.post('/api/images', { headers: {}, data: {prompt: this.$refs.prompt.value,}});

and according to the request payload in my browser it is sending the prompt data but the validation in laravel is telling me that "prompt is required". Here is my validation

$validated = $request->validate(['prompt'=>'required|string']);

Any ideas?

0 likes
12 replies
ruthback's avatar

If I remember correctly, the second argument of Axios is the payload and the third is additional options like headers. So try with:

axios.post('/api/images', { prompt: this.$refs.prompt.value }, { headers: {}} )
aarontharker's avatar

@ruthback thanks but I've tried it both ways already and as I said the request payload clearly shows the prompt being sent to the api endpoint, this is the request payload as per Chrome.

{headers: {}, data: {prompt: "a mouse riding a cat chasing a dog"}}
data: {prompt: "a mouse riding a cat chasing a dog"}
headers: {}
ruthback's avatar
ruthback
Best Answer
Level 6

@aarontharker I don't think you need to specify the data property, that's probably what is tripping Laravel off because it's reading data while it's expecting prompt which is inside data. You could try to specify "data.prompt" in your validation as well, though I'm not entirely sure this will work?

aarontharker's avatar

@ruthback Yep you got that one now I just need to find out why it is not sending the response back :)

return response($filename);

I have double checked and $filename definately has a value but the response data received by axios is saying it has no data data: ""

ruthback's avatar

@aarontharker Here I would guess it's because the response method returns a full response object, but Axios by default will expect JSON data. You can try to use the json method on the response object:

return response()->json(['filename' => $filename], 200, $headers);

https://laravel.com/docs/10.x/helpers#method-response Or, return directly as an array, very similarly:

return ["filename" => $filename];

Or perhaps even on axios, specify the Conten-Type header to accept simple text but I think JSON is usually preferred.

aarontharker's avatar

@ruthback

{
    "Accept": "application/json, text/plain, */*",
    "Content-Type": "application/json",
    "X-Requested-With": "XMLHttpRequest",
    "X-XSRF-TOKEN": "eyJpdiI6ImtMY2ZpODFHbUFoOUM4S1F3NEVlT2c9PSIsInZhbHVlIjoid0syOHRaNnhnRnU3akkxZ1loZkUxNkdIQW1YblgzUmNPaHN4NHFmTWlRYnZaa1lsaFA1SkQ0Tk9uR2JXQU5BcG02VXY3MXBwSitYT0g5MzJ0OXNXb2pCUVFHdXlSWEhOMTVZNHJ0em1uZE1NdERmMkdyOGVOTGdtZ2ZtbU9lcXQiLCJtYWMiOiIzMTVlODhkOGFjMWRhZDYyMWNlNGY3MGM0OGY1MzE2NDdlNTdkNzhhYzFiYThjOTE5ZTMxYmE2M2VjNGJhOWZmIiwidGFnIjoiIn0="
}```

Had already tried the response()->json() route without success.  Ok I don't think the return command is being executed at all!
aarontharker's avatar

This is the full function

public function generateMedia(Request $request)
{
    $validated = $request->validate([
        'prompt'=>'required|string',
    ]);
    $oaClient = \OpenAI::client(env(KEY));
    $prompt = $validated['prompt'];
    ray($prompt);
    $executed = false;
    ray($executed);
    while (!$executed) {
        ray('starting');
        $executed = RateLimiter::attempt(
            'dall-e-3_image',
            $perMinute = 15,
            function() use($oaClient, $prompt) {
                try{
                    $response1 = $oaClient->images()->create([
                        'model' => 'dall-e-3',
                        'prompt' => $prompt,
                        'n' => 1,
                        'size' => '1024x1024',
                        'response_format' => 'url',
                    ]);

                    $url = $response1->data[0]->url;
                    $userAgent = $this->uas[array_rand($this->uas)];
                    $headers = array('User-Agent' => $userAgent);
                    $client = new Client();
                    $response = $client->get($url, $headers);
                    $body = $response->getBody();
                    ray('downloading');

                    // Convert and save the image to a file
                    $filename = uniqid() . '.webp';
                    $store = Storage::disk('gcs')->put('submissions/' . $filename, (string) Image::make($body)->encode('webp'));
                    ray($filename);

                    return ['filename' => $filename];

                } catch (Throwable $t) {
                    Toast::title('Whoops!')
                        ->message($t->getMessage())
                        ->warning()
                        ->leftTop()
                        ->backdrop()
                        ->autoDismiss(15);
                    Log::error($t->getMessage());
                }
            }
        );

        if (!$executed) {
            $sleep = RateLimiter::availableIn('dall-e-3_image');
            Toast::title('Whoops!')
                ->message('Rate Limit exceeded, pausing for '.$sleep.'seconds.  Please be patient.')
                ->warning()
                ->leftTop()
                ->backdrop()
                ->autoDismiss(15);
            sleep($sleep);
        }
    }
}
aarontharker's avatar

I tried returning a 201 response but axios still reported it received a 200 response

ruthback's avatar

Not sure about this one, are you getting errors in the logs? I think a non-resolved response (meaning no explicit return or calls to response) would result in a 200 response. So it's possible something else is not working. But for this issue since it's already different from the original one, I would recommend creating a new thread for this specifically. Someone with more knowledge about Laravel may be able to help better here.

aarontharker's avatar

@ruthback For your interest I figured it out. My return was inside another function so I was just returning that function not the main function, added a second return and all is good.

1 like
ruthback's avatar

@aarontharker Oh, of course I did wonder about that function there but as I'm not familiar with the API I thought it might have been designed this way. Good catch!

Please or to participate in this conversation.