简体   繁体   中英

Missing request token for request

Get all contacts from phonebook and upload to server but got following error.

While append image in request body FormData

在此处输入图片说明

Tried code

pass file url contact thumbnailPath

const path = con.thumbnailPath
body.append('image', {
     uri: path,
     type: 'image/jpeg',
     name: 'photo.jpg',
     type: 'multipart/form-data'
})

Tried code

pass file url contact thumbnailPath without "file://"

const path = con.thumbnailPath.replace('file://', '')
body.append('image', {
     uri: path,
     type: 'image/jpeg',
     name: 'photo.jpg',
     type: 'multipart/form-data'
})

Tried code

check file exist on path or not with using react-native-fs

if (con.thumbnailPath != '') {
     let isExist = RNFS.exists(con.thumbnailPath)
     if (isExist) {
         const path = con.thumbnailPath.replace('file://', '')
         console.log("Exist", path)
         body.append('image', {
             uri: path,
             type: 'image/jpeg',
             name: 'photo.jpg',
             type: 'multipart/form-data'
         })
     }
}

Request

fetch(url, {
    method: 'POST',
    headers: {
        'Authorization': token,
        'token': token
    },
    body: params 
})
.then((res) => res.json())
.then((json) => {
    console.log("RESPONSE:- ", json)
    if (json.response[0].status == 'false') {
        let msg = json.response[0].response_msg
        callback(new Error(msg), json.response[0])
    }
    else {
        callback(null, json.response[0])
    }
})
.catch((err) => {
    console.log(err)
    callback(err, null)
})

The issues comes from react-native@0.63.2 's internal bug.

A quick solution is to revert this commit: https://github.com/facebook/react-native/commit/31980094107ed37f8de70972dbcc319cc9a26339#diff-9a034658197479288c4d346a0eb4d98c

After manually revert this commit in node_modules , recompile the app and the image uploading will be working without any issues.

Replace the function loadImageForURL in /Libraries/Image/RCTLocalAssetImageLoader.mm with the following:

 - (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
                                           size:(CGSize)size
                                          scale:(CGFloat)scale
                                     resizeMode:(RCTResizeMode)resizeMode
                                progressHandler:(RCTImageLoaderProgressBlock)progressHandler
                             partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
                              completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
 {
   __block auto cancelled = std::make_shared<std::atomic<bool>>(false);
   RCTExecuteOnMainQueue(^{
     if (cancelled->load()) {
       return;
     }

     UIImage *image = RCTImageFromLocalAssetURL(imageURL);
     if (image) {
       if (progressHandler) {
         progressHandler(1, 1);
       }
       completionHandler(nil, image);
     } else {
       NSString *message = [NSString stringWithFormat:@"Could not find image %@", imageURL];
       RCTLogWarn(@"%@", message);
       completionHandler(RCTErrorWithMessage(message), nil);
     }
   });

   return ^{
     cancelled->store(true);
   };
 }

此问题已在 0.63.3 中修复 ✅

**For IOS** in 
node_modules/react-native/Libraries/Image/RCTLocalAssetImageLoader.mm   file

**Replace Below** 

 - -(RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
                                               size:(CGSize)size
                                              scale:(CGFloat)scale
                                         resizeMode:(RCTResizeMode)resizeMode
                                    progressHandler:(RCTImageLoaderProgressBlock)progressHandler
                                 partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
                                  completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
{
  UIImage *image = RCTImageFromLocalAssetURL(imageURL);
  if (image) {
    if (progressHandler) {
      progressHandler(1, 1);
    }
    completionHandler(nil, image);
  } else {
    NSString *message = [NSString stringWithFormat:@"Could not find image %@", imageURL];
    RCTLogWarn(@"%@", message);
    completionHandler(RCTErrorWithMessage(message), nil);
  }
  
  return nil;
}

**With**



 - -(RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
                                           size:(CGSize)size
                                          scale:(CGFloat)scale
                                     resizeMode:(RCTResizeMode)resizeMode
                                progressHandler:(RCTImageLoaderProgressBlock)progressHandler
                             partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
                              completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
 {
   __block auto cancelled = std::make_shared<std::atomic<bool>>(false);
   RCTExecuteOnMainQueue(^{
     if (cancelled->load()) {
       return;
     }

     UIImage *image = RCTImageFromLocalAssetURL(imageURL);
     if (image) {
       if (progressHandler) {
         progressHandler(1, 1);
       }
       completionHandler(nil, image);
     } else {
       NSString *message = [NSString stringWithFormat:@"Could not find image %@", imageURL];
       RCTLogWarn(@"%@", message);
       completionHandler(RCTErrorWithMessage(message), nil);
     }
   });

   return ^{
     cancelled->store(true);
   };
 }

This..

Like and Love , if it work 

I have the same issue which perfectly reproducible on one of the iPhone 7 on my react-native project. It's strange but another iPhone 7's works perfectly as well as all Android devices.

My code:

formdata.append("file", {uri: photo.uri, name: name_img, type: 'image/jpeg' });

axios({
   url: `${API}${'/upload'}`,
   method: 'post',
   headers: {
      'Authorization': 'Basic ' + auth_token,
      'Content-Type':'application/x-www-form-urlencoded'
   },
   data: formdata
}).then(response => this.saveRoute())
  .catch(err => {         
     this.props.errorMessage({message: err})
  }
})

Few things that I investigate:

  • I was not able to catch it in debug mode (seams smth wrong in async calls?)
  • I was not able to catch it with try-catch statement but seams it happened in Axios call.

So, I tried to play with Timeout and was able to make it totally unreproducible with 300ms timeout before Axios call .

formdata.append("file", {uri: photo.uri, name: name_img, type: 'image/jpeg' });
    setTimeout(() =>
      axios({
        url: `${API}${'/upload'}`,
        method: 'post',
        headers: {
          'Authorization': 'Basic ' + auth_token,
          'Content-Type':'application/x-www-form-urlencoded'
        },
    data: formdata
  }).then(response => this.saveRoute())
    .catch(err => {
        this.props.errorMessage({message: err})
      }
    })
  , 300);

I know that it's a workaround but may help others to understand the issue for more deep research.

我使用rn-fetch-blob临时修复了这个问题,但这个问题存在于 0.63.2 版本中,我不想修补 node_modules 反应原生图像库。

To send file, you have to create a FormData and append your file into it. See EX: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Uploading_a_file

I found solution. Just put delay when you post request.

let options = {}

options.headers = headers
options.method = 'POST'

let url = {SERVER_URL}

options.body = new FormData();
for (let key in data) {
   options.body.append(key, data[key]);
}
setTimeout(() => {
  fetch(url, options)
    .then((response) => response.json())
    .then((responseJson) => {
         resolve(responseJson);
     })
     .catch((error) => {
         let errParam = {}
         errParam.errMsg = error.toString()
         console.log(errParam)
         resolve(errParam);
    })
}, 1000);

将 React Native 更新到版本 0.63.3 时已修复错误

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