首页 > 解决方案 > 使用 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

标签: phpreactjssafarifetch

解决方案


好吧,案件结案,我的 Infra 团队正在阻止它......

我不太确定他们做了什么,但除了将网站列入白名单之外,他们还必须增加允许的内容长度。

对不起,如果我不能给出更好的解释,不熟悉网络的东西。


推荐阅读