php - 使用 FormData 上传图片获取在 iOS 上不起作用,但在 Android/PC 上有效
问题描述
我为我的 React 站点创建了一个 API,用于使用fetch
. 它适用于 PC 和 Android 手机,直到用户表示他们无法在 iPhone/iPad 上执行此操作时才费心检查 Safari。
插入macbook,看到上传文件时出现CORS错误:
Origin https://xxxxxxx is not allowed by Access-Control-Allow-Origin
有趣的是,当页面加载时,它会调用相同的 API 来检索现有图像,而且效果很好。我的 API 是 PHP,我已经在顶部添加了几行:
header("Access-Control-Allow-Origin: https://xxxxxxx");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: X-Requested-With, Accept, Content-Type, Origin, Content-Length, Accept-Language, Host, User-Agent, Referer, Accept-Encoding, Connection");
基础设施人员发誓他们已经打开了 WAF 以允许上传(我相信他们,因为 PC/Android 手机可以工作)
我曾尝试在 iPhone 上使用 Chrome,但这也不起作用。
所有的提取都通过这个运行:
const API_URL = 'api_url';
const customFetcher = async (formData) => {
let response = fetch(API_URL, {
method: 'POST',
body: formData,
mode: 'cors'
})
.then(r => {
console.log('custom', r.status);
if (r.status === 205) {
throw new Error('Session expired');
} else {
return r;
}
});
return response;
}
export default customFetcher;
引发 CORS 错误的上传获取:
let formData = new FormData();
formData.append('auth', this.props.user.state.token);
formData.append('key', 'le_key')
formData.append('what', 'upload');
formData.append('userId', this.props.user.state.userId);
formData.append('serialNo', this.state.serialNo + '|' + this.state.firstName + '|' + this.state.lastName)
formData.append('photo', this.state.selectedFiles[0]);
customFetcher(formData)
...
获取现有图像的获取:
let formData = new FormData();
formData.append('auth', this.props.user.state.token);
formData.append('key', 'le_key')
formData.append('what', 'photo');
formData.append('userId', this.props.user.state.userId);
formData.append('serialNo', this.state.serialNo + '|' + this.state.firstName + '|' + this.state.lastName);
customFetcher(formData)
.then(r => {
if (r.status !== 404) {
return r.blob();
} else {
this._setNoImage();
return false;
}
})
进展:好的,发现如果我从文件输入中拍一张新照片就可以了!这意味着如果我从文件浏览器中选择,它会发送一个空文件,这会导致此错误。
所以现在的问题是我如何能够获取该选定的文件?我这样做:
<FormControl
type="file"
onChange={this._updateFile}
/>
_updateFile = (e) => {
this.setState({
selectedFiles: e.target.files[0]
})
}
我什至尝试检查文件大小,但它很好,不知何故仍然没有发送任何内容。有任何想法吗?TIA
解决方案
好吧,案件结案,我的 Infra 团队正在阻止它......
我不太确定他们做了什么,但除了将网站列入白名单之外,他们还必须增加允许的内容长度。
对不起,如果我不能给出更好的解释,不熟悉网络的东西。
推荐阅读
- firebase - 如何在不超出资源的情况下对 BigQuery 上导出的 Firebase 数据进行排序?
- javascript - EventListener 在文本输入时触发,但在输入被删除时不触发
- xamarin.forms - 创建 View-ViewModel 查找表时出现问题 - 您为 ViewModels 注册了多个 View
- python - Glade 检测到错误的 Gtk+ 版本
- javascript - 在空输入旁边添加 *Required
- c++ - 如何使用位域将数据从二进制文件复制到结构中?
- reactjs - 你如何使用 jest 和 react-testing-library 测试元素的不存在?
- c++ - 变量超出范围后如何保留向量值?
- python - 如何在 tkinter 中创建任意数量的输入框?
- c++ - 尽管在 openCV 4.0.0 中正确寻址,imread() 仍然返回空垫