'Laravel Livewire Mixed Content error in production

I deployed a Laravel-Livewire on Digital Ocean and now I'm having a Mixed content problem when I try to upload a file. Here is the error: Mixed HTTP error

UploadManager.js:131 Mixed Content: The page at 'https://intake.freejiji.ca/clients/3/extensions' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://intake.freejiji.ca/livewire/upload-file?expires=1625251608&signature=9d98c598db4f6fccc01c009bcfc3051c6a97b56f4058f4d9489a8d30d6d497c2'. This request has been blocked; the content must be served over HTTPS.

The error happens when after I click "Select File" and chose the .csv file I want. Since I'mdoing this on a livewire component I'm not sure how to fix this so that the request goes over HTTPS instead of HTTP.

I was able to fix similar problems on the app by changing "asset()" with "secure_asset()" and "route()" with "secure_url()" but in this case I'm not sure what to do.

Here is the whole "Import" component:

<?php

namespace App\Http\Livewire\Modals;

use Validator;
use Livewire\Component;
use App\Http\Traits\Csv;
use App\Models\AccountUser;
use Livewire\WithFileUploads;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;

class ImportExtensions extends Component
{

use WithFileUploads;

public $clientID;
public $showModal = false;
public $upload;
public $columns;
public $fieldColumnMap = [
    'first_name' => '',
    'last_name' => '',
    'email' => '',
    'password' => '',
    'extension' => '',
    'user_type' => '',
];

protected $rules = [
        'fieldColumnMap.first_name' => 'required|max:255',
        'fieldColumnMap.last_name' => 'required|max:255',
        'fieldColumnMap.email' => 'required|max:255',
        'fieldColumnMap.password' => 'required|max:255',
        'fieldColumnMap.extension' => 'required|max:255',
        'fieldColumnMap.user_type' => 'required|max:255',
];

protected $validationAttributes = [
    'fieldColumnMap.first_name' => 'First Name',
    'fieldColumnMap.last_name' => 'Last Name',
    'fieldColumnMap.email' => 'Email',
    'fieldColumnMap.password' => 'Password',
    'fieldColumnMap.extension' => 'Extension',
    'fieldColumnMap.user_type' => 'User Type',
];

public function updatingUpload($value)
{
    Validator::make(
        ['upload' => $value],
        ['upload' => 'required|mimes:csv'],
    )->validate();
}

public function updatedUpload()
{
    $this->columns = Csv::from($this->upload)->columns();
    $this->guessWhichColumnsMapToWhichFields();
}

public function import()
{
    // Validate that you are importing any data
    $this->validate();

    $importCount = 0;
    Csv::from($this->upload)
    ->eachRow( function ($row) use (&$importCount){
        $eachRow = $this->extractFieldsFromRow($row);

        // Validate each Row of the csv file
        $validatedData = Validator::make([
            'first_name' => $eachRow['first_name'],
            'last_name' => $eachRow['last_name'],
            'email' => $eachRow['email'],
            'password' => $eachRow['password'],
            'extension' => $eachRow['extension'],
            'user_type' => $eachRow['user_type'],
            ],[
            'first_name' => 'required',
            'last_name' => 'required',
            'password' => 'required|max:255',
            'user_type' => 'required|in:user,admin',
            'email' => 'required|email|unique:account_users',
            'extension' => ['required', 'numeric', Rule::unique('account_users', 'extension')
            ->where(function($query)
            {return $query->where("account_id", $this->clientID);
            })],

        ],);

        if($validatedData->fails()){
            $this->notify(['error','Oops something went wrong!']);
        }else{
            AccountUser::create([
                'user_id' => Auth::user()->id,
                'account_id' => $this->clientID,
                'first_name' => $eachRow['first_name'],
                'last_name' => $eachRow['last_name'],
                'email' => $eachRow['email'],
                'password' => $eachRow['password'],
                'extension' => $eachRow['extension'],
                'user_type' => $eachRow['user_type'],
            ]);
            $importCount++;
        }
    });

    $this->reset();
    $this->emit('refreshExtensions');
    if($importCount!=0) $this->notify(['success','Successfully Imported '.$importCount.' Extensions']);
}

public function guessWhichColumnsMapToWhichFields()
{
    $guesses = [
        'first_name' => ['first_name', 'name'],
        'last_name' => ['last_name'],
        'email' => ['email'],
        'password' => ['password', 'pass'],
        'extension' => ['extension', 'ext'],
        'user_type' => ['user_type', 'user', 'type'],
    ];

    foreach ($this->columns as $column) {
        $match = collect($guesses)->search(fn($options) => in_array(strtolower($column), $options));
        if ($match) $this->fieldColumnMap[$match] = $column;
    }
}

public function extractFieldsFromRow($row)
{
    $attributes = collect($this->fieldColumnMap)
        ->filter()
        ->mapWithKeys(function($heading, $field) use ($row) {
            return [$field => $row[$heading]];
        })
        ->toArray();

    return $attributes;
}

public function downloadTemplate()
{
    $filename = 'extensions_template.xls';
    $path = public_path('files/' . $filename);

    return response()->download($path, $filename, [
        'Content-Type' => 'application/vnd.ms-excel',
        'Content-Disposition' => 'inline; filename="' . $filename . '"'
    ]);
}
}


Solution 1:[1]

If you get mixed content problem it is mostly about you fetching the assets or resources from different http scheme. Here you are using HTTP to fetch data in HTTPS site. Change all the links to have HTTPS link.

If you want to force all the routes to use https you can achieve this by using following code.


if(env('APP_ENV', 'production') == 'production') { // use https only if env is production
 \URL::forceScheme('https')
}

The above should solve your problem as all contents now will load from https.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pathros