11

I have a component where I am uploading a video file, everything works fine on my local machine, and it used to work fine on the production server, Namechap is where I host the project, until only recently I have done some work and made changes, that I saw it doesn't work on the production server anymore.

I am using Vue v. 1.0.28, and this is the upload component, where in the fileInputChange() method I am posting form data, to the /upload endpoint, which on the production server for some reason I can't read in the backend:

<template>
  <div class="card-content col-md-10 col-md-offset-1">

      <div v-if="!uploading">
          <div class="col-md-12 Image-input__input-wrapper">
              Upload video
              <input type="file" name="video" id="video" @change="fileInputChange" class="Image-input__input" accept="video/*">
          </div>
      </div>

      <div class="alert alert-danger video-upload-alert" v-if="failed">Something went wrong. Please check the video format and try again. If you need any help please contact our <a>support service.</a></div>

      <div id="video-form">
          <div class="alert alert-info" v-if="uploading && !failed && !uploadingComplete">
              Please do not navigate away from this page, until the video has finished uploading. Your video will be available at <a href="{{ $root.url }}/videos/{{ uid }}" target="_blank">{{ $root.url }}/videos/{{ uid }}</a>, once uploaded.
          </div>

          <div class="alert alert-success" v-if="uploading && !failed && uploadingComplete">
              Upload complete. Video is now processing. <a href="/videos">Go to your videos</a>.
          </div>

          <div class="progress" v-if="uploading && !failed && !uploadingComplete">
              <div class="progress-bar" v-bind:style="{ width: fileProgress + '%' }"></div>
          </div>

          <div class="row">
              <div class="col-md-12 form-group">
                  <label for="title" class="control-label">Title</label>
                  <input type="text" class="form-control" v-model="title">
              </div>
              <!--
              <div class="col-md-12 form-group">
                  <label for="visibility" class="control-label">Visibility</label>
                  <select class="form-control" v-model="visibility">
                      <option value="private">Private</option>
                      <option value="unlisted">Unlisted</option>
                      <option value="public">Public</option>
                  </select>
              </div>
              -->
          </div>

          <div class="row">
              <div class="col-md-12 form-group">
                  <label for="description" class="control-label">Description</label>
                  <textarea class="form-control" v-model="description"></textarea>
              </div>
          </div>

          <div class="row">
              <div class="col-md-12 form-group">
                  <button type="submit" class="btn btn-submit" @click.prevent="update">Save</button>
              </div>
          </div>
          <div class="row">
              <div class="col-md-12 form-group">
                  <span class="help-block pull-right">{{ saveStatus }}</span>
              </div>
          </div>
  </div>
</template>

<script>
    function initialState (){
        return {
            uid: null,
            uploading: false,
            uploadingComplete: false,
            failed: false,
            title: null,
            link: null,
            description: null,
            visibility: 'private',
            saveStatus: null,
            fileProgress: 0
        }
    }
    export default {
        data: function (){
            return initialState();
        },
        methods: {
            fileInputChange() {
                this.uploading = true;
                this.failed = false;

                this.file = document.getElementById('video').files[0];

                var isVideo = this.isVideo(this.file.name.split('.').pop());

                if (isVideo) {
                  this.store().then(() => {
                      var form = new FormData();

                      form.append('video', this.file);
                      form.append('uid', this.uid);

                      this.$http.post('/upload', form, {
                          progress: (e) => {
                              if (e.lengthComputable) {
                                  this.updateProgress(e)
                              }
                          }
                      }).then(() => {
                          this.uploadingComplete = true
                          this.uploading = false
                      }, () => {
                          this.failed = true
                          this.uploading = false
                      });
                  }, () => {
                      this.failed = true
                      this.uploading = false
                  })
                }
                else {
                  this.failed = true
                  this.uploading = false
                }
            },
            isVideo(extension) {
                switch (extension.toLowerCase()) {
                case 'm4v':
                case 'avi':
                case 'mpg':
                case 'mp4':
                case 'mp3':
                case 'mov':
                case 'wmv':
                case 'flv':
                    return true;
                }
                return false;
            },
            store() {
                return this.$http.post('/videos', {
                    title: this.title,
                    description: this.description,
                    visibility: this.visibility,
                    extension: this.file.name.split('.').pop()
                }).then((response) => {
                    this.uid = response.json().data.uid;
                });
            },
            update() {
                this.saveStatus = 'Saving changes.';

                return this.$http.put('/videos/' + this.uid, {
                    link: this.link,
                    title: this.title,
                    description: this.description,
                    visibility: this.visibility
                }).then((response) => {
                    this.saveStatus = 'Changes saved.';

                    setTimeout(() => {
                        this.saveStatus = null
                    }, 3000)
                }, () => {
                    this.saveStatus = 'Failed to save changes.';
                });
            },
            updateProgress(e) {
                e.percent = (e.loaded / e.total) * 100;
                this.fileProgress = e.percent;
            },
        }
    }
</script>

The problem is that on upload in my controller in the store function the request object is empty on the production server, which I got when I did dd($request->all()). Then it fails to find the video, in the network inspector I get a 404 error, which is returned by firstOrFail() method, because it can't find the Video model, since it is missing $request->uid.

No query results for model [App\Video].

This is the controller:

class VideoUploadController extends Controller
{
    public function index()
    {
      return view('video.upload');
    }

    public function store(Request $request)
    {
      $player = $request->user()->player()->first();

      $video = $player->videos()->where('uid', $request->uid)->firstOrFail();

      $request->file('video')->move(storage_path() . '/uploads', $video->video_filename);

      $this->dispatch(new UploadVideo(
          $video->video_filename
      ));

      return response()->json(null, 200);
    }
}

I am not sure what is going on, since on inspecting the network tab in the console I am sending a request payload that looks like this:

------WebKitFormBoundarywNIkEqplUzfumo0A Content-Disposition: form-data; name="video"; filename="Football Match Play.mp4" Content-Type: video/mp4

------WebKitFormBoundarywNIkEqplUzfumo0A Content-Disposition: form-data; name="uid"

159920a7878cb2 ------WebKitFormBoundarywNIkEqplUzfumo0A--

It is really frustrating since I have no idea how to fix this, when everything is fine on my local machine, not sure what is wrong on the production server and how to fix it?

Update

It started working again on its own, since I have created a ticket in the Namecheap support service, all of sudden after one day, it started working again, I haven't done any changes, and on asking the Namecheap support I have got an answer from them that they haven't done any changes either, so I have no idea what went wrong, which is still a bit frustrating since I would like to avoid that in the future, but at least everything is working now again as it should.

12
  • Take a look in your browser's network inspector. I'd bet there's a validation error that's causing a 422 response or a 302 redirect. Commented Aug 12, 2017 at 13:40
  • No, there is not a validation error, like I said, I have the same scripts and it works on the local machine Commented Aug 12, 2017 at 13:46
  • That doesn't mean it's not a validation error. Have you checked what's happening in the network inspector? Do you see the file in the request, and do you see a response code you're expecting? Commented Aug 12, 2017 at 13:56
  • I have checked the $request that I am getting in the controller method, and the if do $request->all() I get the empty object Commented Aug 12, 2017 at 14:11
  • 4
    For the third time, have you checked what's happening in the network inspector? Commented Aug 12, 2017 at 14:46

1 Answer 1

1

Laravel's $request->all() method only pulls from the input, thus in the store() method of VideoUploadController $request->all() return empty object.

In your script, it calls this.store() after checked the isVideo is true while file changes. As a result, there isn't a uid parameter or video parameter.

Sign up to request clarification or add additional context in comments.

2 Comments

If I do $request->all() locally I get a uid and a file
I think something is wrong with your webserver configuration. Which server do you use? Nginx or Apache?

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.