简体   繁体   中英

Angular / Rails net::ERR_TOO_MANY_REDIRECTS on update

In my Rails app I have included a small angular app, which uses a plug-in to upload a file to Amazon S3. The code is embedded in a rails page.

After the file is successfully uploaded to S3, I wish to save the S3 key (a string) in the Rails backend using the Rails update action. I then wish to redirect to the show action on the same rails controller. The job of Angular is finished then, and there is no Angular on the show page.

So far it is all working, including the successful save of the update, and there is no error from Rails, but Angular emits the dreaded "net::ERR_TOO_MANY_REDIRECTS" error.

Note that I am not using any Angular routing, and in fact would like to avoid doing so and have Rails control page refreshes.

Rails controller code:

  def update
    respond_to do |format|
     if @user.update(secure_params)
       format.html { redirect_to @user }
       format.json { head :no_content }
       format.js
     else
       format.json { render json: @user.errors.full_messages,
                                  status: :unprocessable_entity }
     end
   end
 end

Angular update

 $scope.upload = function (dataUrl, file) {
    $scope.aws_file_key = $scope.aws.key + file.name;
    Upload.upload({
        url: $scope.aws.url,
        method: 'POST',
        data: {
            key: $scope.aws_file_key,
            AWSAccessKeyId: $scope.aws.access_key,
            acl: $scope.aws.acl,
            policy: $scope.aws.policy,
            signature: $scope.aws.signature,
            "Content-Type": file.type != '' ? file.type : 'application/octet-stream',
            file: file
        },
    }).then(function (response) {
        console.log('updateUser');
        $timeout(function () {
          updateUser();
        });
    }, function (response) {
        console.log('response');
        if (response.status > 0) $scope.errorMsg = response.status
            + ': ' + response.data;
    }, function (evt) {
        console.log('evt');
        $scope.progress = parseInt(100.0 * evt.loaded / evt.total);
    });
}

function updateUser() {
  $http({
     method: 'PATCH',
     url: '/users/' + $scope.user.id,
     dataType: 'json',
     contentType: 'application/json',
     data: {user: { profile_image_s3_key: $scope.aws_file_key }}
  });  // $http
}  // updateUser()

在此处输入图片说明

I did this because I wanted to use some excellent Angular file upload / resize, and this fiddle inspired me: http://jsfiddle.net/danialfarid/xxo3sk41/590/

Well I worked it out, the solution is a bit messy but avoids have a full-blown Angular app with routing, Rails API etc. I needed two things to make it work:

  • perform the redirection with Angular and not Rails, within the returned promise from the update

  • pass in headers of application/json so Rails executes the format.json respond_to instead of defaulting to format.html

    headers: { 'Accept': 'application/json' }

Working code

  $scope.upload = function (dataUrl, file) {
    $scope.aws_file_key = $scope.aws.key + file.name;
    Upload.upload({
        url: $scope.aws.url,
        method: 'POST',
        data: {
            key: $scope.aws_file_key,
            AWSAccessKeyId: $scope.aws.access_key,
            acl: $scope.aws.acl,
            policy: $scope.aws.policy,
            signature: $scope.aws.signature,
            "Content-Type": file.type != '' ? file.type : 'application/octet-stream',
            file: file
        },
    }).then(function (response) {
        console.log('updateUser');
        $timeout(function () {
          updateUser();
        });
    }, function (response) {
        console.log('response');
        if (response.status > 0) $scope.errorMsg = response.status
            + ': ' + response.data;
    }, function (evt) {
        console.log('evt');
        $scope.progress = parseInt(100.0 * evt.loaded / evt.total);
    });
}

function updateUser() {
  $http({
     method: 'PATCH',
     url: '/users/' + $scope.user.id,
     dataType: 'json',
     contentType: 'application/json',
     headers: { 'Accept': 'application/json' },
     data: {user: { profile_image_s3_key: $scope.aws_file_key }}
  }).then(function(data){
      // assumes all OK
      // TODO add in error checking
      $window.location.href = '/users/' + $scope.user.id;
  })  // $http
}  // updateUser()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM