React Native 用 axios 上传文件 PHP 后端接收不到,是二者之间传输协议问题吗?

2018-04-23 09:20:04 +08:00
 Aluhao

这坑好几天了没填满呀,我用 html 加载 axios 都可以上传,在 RN 里就不行了,有没有遇到类似问题的? HTML 写法

var data = new FormData();

data.append('avatar', $('#file')[0].files[0]);

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

axios.post('http://127.0.0.1//api/post/', data)

.then(function (response) {

console.log(response);

}) .catch(function (error) {

console.log(error);

});

});

在 RN 里也是用 FormData 为么就不行?

4520 次点击
所在节点    问与答
17 条回复
swirling
2018-04-23 09:25:15 +08:00
form data 是浏览器的 API. 你 RN 哪里有浏览器?
Aluhao
2018-04-23 09:26:11 +08:00
@swirling 请教一下,RN 有什么方式呀?
Aluhao
2018-04-23 09:28:12 +08:00
@swirling FormData 这个是构造虚拟表单,RN 应该支持吧。
SourceMan
2018-04-23 09:30:26 +08:00
帮你使用 Google 搜索了关键字 ·fetch file upload react native·
https://github.com/g6ling/React-Native-Tips/tree/master/How_to_upload_photo%2Cfile_in%20react-native
这篇文章里有提到 new FormData();
Pastsong
2018-04-23 09:34:59 +08:00
form data 的 content type 不是 urlencode...
Aluhao
2018-04-23 09:39:27 +08:00
@Pastsong 用 application/octet-stream 和 multipart/form-data 都试过了都不行,PHP 后台接收不到
chairuosen
2018-04-23 09:41:44 +08:00
RN 能用 jQuery ?
my101du
2018-04-23 09:46:38 +08:00
在 html 里能上传,是指 post 数据到 http://127.0.0.1 正常,对吗?
到 RN 里后端 php 接收不到数据,是不是因为 RN 编译成 app 后,http://127.0.0.1 是指向“这台手机 /模拟器”?
wasabia
2018-04-23 09:47:57 +08:00
var xhr = new XMLHttpRequest();
var url = "xxxx";
xhr.open('POS', url);
var formdata = new FormData();

_.map(images, (image, index) => {
formdata.append('photos[]', {type: "image/jpeg", name: 'image.jpg', uri: image.path});
})

xhr.onload = () => {

}
xhr.send(formdata);
Manweill
2018-04-23 10:01:20 +08:00
['Content-Type']='multipart/form-data' 后台是可以收到的

var formdata = new FormData();
formdata.append('file', {type: "image/jpeg", name: 'image.jpg', uri: image.path});
axios({url,formdata})
Manweill
2018-04-23 10:02:21 +08:00
参数写错了,应该是这样

var data = new FormData();
formdata.append('file', {type: "image/jpeg", name: 'image.jpg', uri: image.path});
axios({url,data})
Aluhao
2018-04-23 10:02:54 +08:00
@Manweill
@wasabia
谢谢!
Aluhao
2018-04-23 10:03:56 +08:00
@chairuosen 那个是网页测试的
luwu1991
2018-04-23 10:53:27 +08:00
抓包,看看 2 种情况下的上传请求有啥不同
wentaoliang
2018-04-23 12:48:29 +08:00
为啥我印象中 axios 是 post 的是 json 的格式 php 要用 file://input 接收
dilu
2018-04-23 21:46:31 +08:00
我用的是 react-native-fetch-blob
RN 中是这样写的
```
handleSelectPhoto = () => {
SYImagePicker.asyncShowImagePicker(options)
.then(photos => {

if(photos[0])//如果选择了图片
{
console.log('upload start');
RNFetchBlob.fetch("POST",config.baseUrl + config.avatarUpload,{
'Content-Type' : 'multipart/form-data',
'token':user.password,
'phone':user.teacher_phone,
'isparent':0,
},[
{
name:'file',
filename:photos[0]['uri'],
type:'image/jpg',
data: RNFetchBlob.wrap(photos[0]['uri'])
}
])
.then((response) => response.json())
.then((response) => {
if(1 != response.code)
{
Toast.fail(response.msg);
return false;
}
Toast.info(response.msg);
this.setState({
userAvatar:{uri:config.local + '/public' + response.data.url}
});

})
.catch((err) => {
console.log(err);
Toast.fail('网络异常');
})

console.log(user);
}
})
.catch(err => {

})
}
```

后端是这样写的

```
public function upload()
{

$file = $this->request->file('file');
if (empty($file))
{
$this->error(__('No file upload or server upload limit exceeded'));
}

//判断是否已经存在附件
$sha1 = $file->hash();

$upload = Config::get('upload');

preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
$type = strtolower($matches[2]);
$typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
$size = (int) $upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
$fileInfo = $file->getInfo();
$suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
$suffix = $suffix ? $suffix : 'file';

$mimetypeArr = explode(',', $upload['mimetype']);
$typeArr = explode('/', $fileInfo['type']);
//验证文件后缀
if ($upload['mimetype'] !== '*' && !in_array($suffix, $mimetypeArr) && !in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr))
{
$this->error(__('Uploaded file format is limited'));
}
$replaceArr = [
'{year}' => date("Y"),
'{mon}' => date("m"),
'{day}' => date("d"),
'{hour}' => date("H"),
'{min}' => date("i"),
'{sec}' => date("s"),
'{random}' => Random::alnum(16),
'{random32}' => Random::alnum(32),
'{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
'{suffix}' => $suffix,
'{.suffix}' => $suffix ? '.' . $suffix : '',
'{filemd5}' => md5_file($fileInfo['tmp_name']),
];
$savekey = $upload['savekey'];
$savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);

$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
$fileName = substr($savekey, strripos($savekey, '/') + 1);
//
$splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
if ($splInfo)
{
$imagewidth = $imageheight = 0;
if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']))
{
$imgInfo = getimagesize($splInfo->getPathname());
$imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
}
$params = array(
'filesize' => $fileInfo['size'],
'imagewidth' => $imagewidth,
'imageheight' => $imageheight,
'imagetype' => $suffix,
'imageframes' => 0,
'mimetype' => $fileInfo['type'],
'url' => $uploadDir . $splInfo->getSaveName(),
'uploadtime' => time(),
'storage' => 'local',
'sha1' => $sha1,
);
$attachment = model("attachment");
$attachment->data(array_filter($params));
$attachment->save();
\think\Hook::listen("upload_after", $attachment);
//进行身份判断 将头像 url 写入到数据库中
if(isset($this->user['teacher_phone']))
{
db('teacher')->where('teacher_phone',$this->user['teacher_phone'])
->setField('avatar',$uploadDir . $splInfo->getSaveName());
}
else if (isset($this->user['parent_phone']))
{

db('parents')->where('parent_phone',$this->user['parent_phone'])
->setField('avatar',$uploadDir . $splInfo->getSaveName());
}

$this->success(__('Upload successful'), $attachment);
}
else
{
// 上传失败获取错误信息
$this->error($file->getError());
}
}
```
希望能帮到你
Aluhao
2018-04-24 09:55:47 +08:00
@dilu 谢谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/449002

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX