title: CodeIgniter 4 - error "404 (File Not Found)"
body: <p>I'm integrating the <a href="https://en.wikipedia.org/wiki/Google_Drive" rel="nofollow noreferrer">Google Drive</a> API for uploading files from an HTML form to Google Drive. It works fine when I implement the code (Ajax and jQuery) in CorePHP, but it doesn't work in CodeIgniter 4. Is the issue due to the URL?</p>
  <p>The web browser's console shows an error:</p>
  <blockquote>
  <p>GET http://localhost:8080/upload.html?code=4/0AX4XfWgb3ql4RL2FfY7RdaL7jgyDOYT3CztsruXIbiLNdziDJKZ_UWFNK3qNzEgdcZrMFQ&amp;scope=https://www.googleapis.com/auth/drive 404 (Not Found)</p>
  </blockquote>
  <p>File <em>index.html</em> (for log in to the Google account):</p>
  <pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;meta charset=&quot;utf-8&quot; /&gt;
      &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
      &lt;title&gt;Git Login App&lt;/title&gt;
      &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
      &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
      &lt;script src=&quot;main.js&quot;&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
     &lt;div&gt;
         &lt;button id=&quot;login&quot;&gt;
             Upload Files to Drive
         &lt;/button&gt;
     &lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <p>File <em>main.js</em> (redirects to <em>upload.html</em> for uploading files to Google Drive):</p>
  <pre class="lang-javascript prettyprint-override"><code>$(document).ready(function() {
  
      // Client id of the project
      var clientId = &quot;&quot;;
  
      // redirect_uri of the project
      var redirect_uri = &quot;http://localhost:8080/upload.html&quot;;
  
      // Scope of the project
      var scope = &quot;https://www.googleapis.com/auth/drive&quot;;
  
      // The URL to which the user is redirected to
      var url = &quot;&quot;;
  
      // This is event click listener for the button
      $(&quot;#login&quot;).click(function() {
  
          // This is the method which will be invoked it takes four parameters
  
          signIn(clientId, redirect_uri, scope, url);
      });
  
      function signIn(clientId, redirect_uri, scope, url) {
  
          // The actual URL to which the user is redirected to
          url = &quot;https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=&quot; + redirect_uri +
          &quot;&amp;prompt=consent&amp;response_type=code&amp;client_id=&quot; + clientId + &quot;&amp;scope=&quot; + scope +
          &quot;&amp;access_type=offline&quot;;T
  
          // This line makes the user redirected to the URL
          window.location = url;
      }
  });
  </code></pre>
  <p>File <em>upload.html</em>:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;meta charset=&quot;utf-8&quot;/&gt;
      &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
      &lt;title&gt;Git Login App&lt;/title&gt;
      &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
      &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;upload.css&quot;/&gt;
      &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
      &lt;script src=&quot;upload.js&quot;&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
     &lt;div&gt;
       &lt;input id=&quot;files&quot; type=&quot;file&quot; name=&quot;files[]&quot; multiple/&gt;
       &lt;button id=&quot;upload&quot;&gt;Upload&lt;/button&gt;
       &lt;div id=&quot;progress-wrp&quot;&gt;
          &lt;div class=&quot;progress-bar&quot;&gt;&lt;/div&gt;
          &lt;div class=&quot;status&quot;&gt;0%&lt;/div&gt;
      &lt;/div&gt;
     &lt;/div&gt;
     &lt;div id=&quot;result&quot;&gt;
  
     &lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <p>File <em>upload.js</em>:</p>
  <pre class="lang-javascript prettyprint-override"><code>$(document).ready(function() {
  
      const urlParams = new URLSearchParams(window.location.search);
      const code = urlParams.get('code');
      const redirect_uri = &quot;http://localhost:8080/upload.html&quot; // Replace with your redirect_uri;
      const client_secret = &quot;&quot;; // Replace with your client secret
      const scope = &quot;https://www.googleapis.com/auth/drive&quot;;
      var access_token = &quot;&quot;;
      var client_id = &quot;&quot; // Replace it with your client id;
  
      $.ajax({
          type: 'POST',
          url: &quot;https://www.googleapis.com/oauth2/v4/token&quot;,
          data: {code: code,
                 redirect_uri: redirect_uri,
                 client_secret: client_secret,
                 client_id: client_id,
                 scope: scope,
                 grant_type: &quot;authorization_code&quot;},
                 dataType: &quot;json&quot;,
                 success: function(resultData) {
                     localStorage.setItem(&quot;accessToken&quot;, resultData.access_token);
                     localStorage.setItem(&quot;refreshToken&quot;, resultData.refreshToken);
                     localStorage.setItem(&quot;expires_in&quot;, resultData.expires_in);
                     window.history.pushState({}, document.title, &quot;/GitLoginApp/&quot; + &quot;upload.html&quot;);
                 }
      });
  
      function stripQueryStringAndHashFromPath(url) {
          return url.split(&quot;?&quot;)[0].split(&quot;#&quot;)[0];
      }
  
      var Upload = function (file) {
          this.file = file;
      };
  
      Upload.prototype.getType = function() {
          localStorage.setItem(&quot;type&quot;, this.file.type);
          return this.file.type;
      };
  
      Upload.prototype.getSize = function() {
          localStorage.setItem(&quot;size&quot;, this.file.size);
          return this.file.size;
      };
  
      Upload.prototype.getName = function() {
          return this.file.name;
      };
  
      Upload.prototype.doUpload = function () {
          var that = this;
          var formData = new FormData();
  
          // Add assoc key values. This will be posts values
          formData.append(&quot;file&quot;, this.file, this.getName());
          formData.append(&quot;upload_file&quot;, true);
  
          $.ajax({
              type: &quot;POST&quot;,
              beforeSend: function(request) {
                  request.setRequestHeader(&quot;Authorization&quot;, &quot;Bearer&quot; + &quot; &quot; + localStorage.getItem(&quot;accessToken&quot;));
              },
              url: &quot;https://www.googleapis.com/upload/drive/v2/files&quot;,
              data:{
                  uploadType: &quot;media&quot;
              },
              xhr: function () {
                  var myXhr = $.ajaxSettings.xhr();
                  if (myXhr.upload) {
                      myXhr.upload.addEventListener('progress', that.progressHandling, false);
                  }
                  return myXhr;
              },
              success: function (data) {
                  console.log(data);
              },
              error: function (error) {
                  console.log(error);
              },
              async: true,
              data: formData,
              cache: false,
              contentType: false,
              processData: false,
              timeout: 60000
          });
      };
  
      Upload.prototype.progressHandling = function (event) {
          var percent = 0;
          var position = event.loaded || event.position;
          var total = event.total;
          var progress_bar_id = &quot;#progress-wrp&quot;;
          if (event.lengthComputable) {
              percent = Math.ceil(position / total * 100);
          }
          // Update progressbars classes so it fits your code
          $(progress_bar_id + &quot; .progress-bar&quot;).css(&quot;width&quot;, +percent + &quot;%&quot;);
          $(progress_bar_id + &quot; .status&quot;).text(percent + &quot;%&quot;);
      };
  
      $(&quot;#upload&quot;).on(&quot;click&quot;, function (e) {
          var file = $(&quot;#files&quot;)[0].files[0];
          var upload = new Upload(file);
  
          // Maybe check size or type here with upload.getSize() and upload.getType()
  
          // Execute upload
          upload.doUpload();
      });
  
  });
  </code></pre>
  <p><sub>I'm new to CodeIgniter 4.</sub></p>