缺少请求的请求令牌

时间:2019-02-13 06:27:46

标签: javascript ios react-native request multipartform-data

从电话簿中获取所有联系人并上传到服务器,但出现以下错误。

在请求正文FormData中添加图片

enter image description here

尝试过的代码

传递文件网址联系方式thumbnailPath

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

尝试过的代码

传递文件网址联系人缩略图路径不带“ file://”

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

尝试过的代码

使用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'
         })
     }
}

请求

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)
})

8 个答案:

答案 0 :(得分:12)

问题来自react-native@0.63.2的内部错误。

一种快速的解决方案是还原此提交:https://github.com/facebook/react-native/commit/31980094107ed37f8de70972dbcc319cc9a26339#diff-9a034658197479288c4d346a0eb4d98c

node_modules中手动还原此提交后,重新编译应用程序,图像上传将正常进行。

loadImageForURL中的函数/Libraries/Image/RCTLocalAssetImageLoader.mm替换为以下内容:

 - (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);
   };
 }

答案 1 :(得分:2)

在我的本机项目中,我遇到的问题完全可以在一部iPhone 7上重现。很奇怪,但是另一部iPhone 7可以与所有Android设备完美配合。

我的代码:

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})
  }
})

我要调查的几件事:

  • 我无法在调试模式下捕获它(异步调用中缝隙错了吗?)
  • 我无法通过try-catch语句来捕获它,但是接缝是在Axios调用中发生的。

所以,我尝试使用Timeout,并且能够在Axios调用之前 300ms超时中使其完全不可复制。

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);

我知道这是一种解决方法,但可以帮助其他人了解该问题以进行更深入的研究。

答案 2 :(得分:2)

**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 

答案 3 :(得分:1)

我使用rn-fetch-blob进行了临时修复,但该问题在0.63.2版本中存在,我不想修补node_modules react-native图像库。

答案 4 :(得分:1)

此问题已在0.63.3 is中修复

答案 5 :(得分:0)

要发送文件,必须创建一个FormData并将文件附加到其中。参见EX:https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Uploading_a_file

答案 6 :(得分:0)

我找到了解决方案。只需在发布请求时放置延迟即可。

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);

答案 7 :(得分:0)

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