javascript - Ajax调用问题

标签 javascript ruby-on-rails ajax reactjs react-redux

我正在通过 ajax 调用发送图像属性文件。但 post api 可能会因此不断中断。我想将文件推送到 formData 中的图像属性数组中并成功调用 api。

我的Api表单数据配置如下图所示: enter image description here

当我在控制台上检查 formData 图像属性数组时,我得到了图像属性[]:[对象文件],如下图所示: enter image description here & 我的 api 不断失败并显示以下错误: enter image description here 以下是我目前所坚持的代码:

/*NewPost.jsx */

handleSubmit = (event) => {
        event.preventDefault();
        console.log("Submitting")
        let error = this.areThereAnyErrors();
        if(!error){
          let data = {};
          data.description = this.state.description.value || "";
          // console.log(this.state.images_attributes);
          data.images_attributes = this.state.images_attributes[0] || null;
          let brand_string = this.state.brand_ids[0].value;
          let brands_list = this.props.auto_complete_details.brand_json;
          let selected_brand = brands_list.find(function (brand) {
            return brand.brand_name.toLowerCase() == brand_string.toLowerCase();
          });
          if(selected_brand){
            this.state.brand_selected.value = selected_brand.brand_id;
          }

          if(this.state.brand_selected.value){
            data.Brand = this.state.brand_selected.value;
          } else {
            // console.log(this.state.brand_ids);
            data.custom_brand = this.state.brand_ids[0].value;
          }


          let product_string = this.state.product_ids[0].value;
          let product_list = this.props.auto_complete_details.product_json;
          let selected_product = product_list.find(function (product) {
            return product.product_name.toLowerCase() == product_string.toLowerCase();
          });
          if(selected_product){
            this.state.product_selected.value = selected_product.product_id;
          }


          if(this.state.product_selected.value){
            data.Product = this.state.product_selected.value;
          } else {
            data.custom_product = this.state.product_ids[0].value;
          }

          data.Price = this.state.price.value;
          this.props.onFormSubmit(data);
   }
 }

render() {
    return(
      <form onSubmit={this.handleSubmit}>
        <div className={"row description new_post_desc "+error_class}>
          <div className="col-md-12 col-xs-12" style={{"paddingRight":"0px"}}>
              <textarea id="new_post_desc" name="description" className='new-post-description'   placeholder="Share your brand story..."  ref={(input) => {this.state.description = input}}/>
          </div>
        </div>
        <div className="description">
            <div className="row">
              <input id="new_post_image" className={this.state.errors.images_attributes ? "error-input disp_inline": "disp_inline"} type="file" name="image" accept="image/*" ref={(input) => {this.state.images_attributes[0] = input}} />
            </div>
            <div className="row margin-top-10">
              <div className="col-md-2 col-sm-2 col-xs-3 new_post_spacing">
                <input id='autocomplete_brand' className={this.state.errors.brand_ids ? 'typeahead error-input new_post_capsules tt-hint hint_user_info' : 'typeahead new_post_capsules hint_user_info'} type="text" name="brand" placeholder="Brand" ref={(input) => {this.state.brand_ids[0] = input}}/>
                <input id="brand_value_selected" style={{display: "none"}} value="" ref={(input) => {this.state.brand_selected = input}}/>
              </div>
              <div className="col-md-2 col-sm-2 col-xs-3 new_post_spacing">
                <input id='autocomplete_product' className={this.state.errors.product_ids ? 'typeahead error-input new_post_capsules tt-hint hint_user_info' : 'typeahead new_post_capsules hint_user_info'} type="text" name="product" placeholder="Product" ref={(input) => {this.state.product_ids[0] = input}}/>
                <input id="product_value_selected" style={{display: "none"}} value="" ref={(input) => {this.state.product_selected = input}} />
              </div>
              <div className="col-md-2 col-sm-2 col-xs-3 new_post_spacing">
                <input id='autocomplete_price' className={this.state.errors.price ? 'typeahead new_post_capsules tt-hint hint_user_info error-input' : 'typeahead new_post_capsules tt-hint hint_user_info'} type="number" name="price" placeholder="Price" ref={(input) => {this.state.price = input}}/>
              </div>
              <div className="col-md-2 col-sm-2 col-xs-3 new_post_spacing">
                <button type="submit" className="btn button-styling" style={{"outline":"none"}} disabled={this.props.new_post_creation_in_progress}>Share { loading_icon }</button>  
              </div>
            </div>     
        </div>
        <div className="row">
            { this.state.has_errors ? <div className="error_mesg">* Please provide required information</div> : '' }
        </div>
    </form>
  );
}

const mapDispatchToProps = (dispatch, ownProps) => {
  var that = this;
  return {
    dispatch,
    onFormSubmit: (data) => {
        dispatch(getNewPostDetails(data));
    }
  };
}

/* Actions/index.js */

export const getNewPostDetails = (data) => {


console.log(data);
  var data_value = data;
  return function(dispatch) {
    var formData = new FormData();

    // add assoc key values, this will be posts values
    // setting form data

    console.log(data_value);

    //for image files
    if(data_value.images_attributes) {
      formData.append('images_attributes[]', $('input[type=file]')[0].files[0]);
    }


    //for video files
    formData.append('video_attributes[]', null);

    //for custom brands
    if(data_value.custom_brand) {
      formData.append('brand_ids[]', data_value.custom_brand);
    }

    //for products
    if(data_value.custom_product) {
      formData.append('product_ids[]', data_value.custom_product);
    }

    //For Price & Description
    formData.append('price', data_value.Price);
    formData.append('description', data_value.description);

    for (let pair of formData.entries()) {
      console.log(pair[0] + ': ' + pair[1]); 
    }

    $.ajax({
      type: "POST",
      url: `${mainurl}/api/v1/posts`,
      // headers: checkAuthHeaders(), // the main solution
      formData: formData,
      beforeSend: function(){
        $("#new_post_desc").prop('disabled', true);
        $("#autocomplete_brand").prop('disabled', true);
        $("#autocomplete_product").prop('disabled', true);
        $("#autocomplete_price").prop('disabled', true);
        dispatch(createPostProgress(true));
       },
      success: function(resp) {
        $('#new_post_desc').val("");
        $('#new_post_image').val("");
        $('#autocomplete_brand').val("");
        $('#autocomplete_product').val("");
        $('#autocomplete_price').val("");
        $("#brand_value_selected").val("");
        $("#product_value_selected").val("");
        $("#new_post_desc").prop('disabled', false);
        $("#autocomplete_brand").prop('disabled', false);
        $("#autocomplete_product").prop('disabled', false);
        $("#autocomplete_price").prop('disabled', false);

        dispatch(receiveNewPostDetails(resp));
        dispatch(resetNewPostFlag());
        dispatch(createPostProgress(false));
      },
      error: function(error) {
        dispatch(createPostProgress(false));
      },
      async: true,
      cache: false,
      contentType: false,
      processData: false,
      timeout: 60000
    });
  };
}

最佳答案

[] 在属性名称的末尾,通常已经表示该字段是一个数组,而该字段的值不应该是数组。所以尝试使用:

formData.append('images_attributes[]', files[0]);
formData.append('images_attributes[]', files[1]);
formData.append('images_attributes[]', files[2]);
// etc..

而不是

formData.append('images_attributes[]', files);

同样的规则适用于其他字段。

关于javascript - Ajax调用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49347232/

相关文章:

ruby-on-rails - 由于 `require' : cannot load such file -- bcrypt_ext (LoadError),Rails 服务器无法启动

ios - 使用 xml 或 css 或全局变量的数据驱动 ios-Calabash 自动化测试

javascript - 在 JavaScript 中使用三元运算符来调用两个函数

javascript - 无需 css 过渡的 jQuery 扩展菜单缓动

javascript - 输入 key 表单提交因 HTML5 日期输入而失败

html - Air: 安装时写入应用程序存储目录?

javascript - Spring MVC : No handler found for portlet request: mode 'view' ,阶段 'Resource_PHASE'

php - AJAX 将检索到的值显示为未定义

ruby-on-rails - Ruby on Rails对象及其属性的深层复制/深层克隆

javascript - 带有ajax的jquery json来查询flickr