如何通过表单在HTTP请求中发送图像,以及使用什么标头?

huangapple go评论60阅读模式
英文:

How to send by form an image in http request, and with what headers?

问题

我在谷歌上搜索了一下,没有找到答案...

在我的VueJS视图中有一个表单:

  <form @submit.prevent="avatar()" method="POST" enctype="multipart/form-data">
    <input type="file" name="profilePicture" id="profilepicture">
    <button type="submit">Valider mon avatar?</button>
  </form>

用户会发送一张图片。

我的问题是,我想要将用户提交的图像发送到一个函数中,然后这个函数将图像添加到 HTTP 请求的头部...

API 请求以如下方式开始:

app.post('/myupload/:iduser', async (req, res) => {
    try {
        var { iduser } = req.params;
        const { image } = req.file;
        [...]

我VueJS 视图中的函数如下:

async function avatar() {

    console.log(document.getElementById("profilepicture").value);
    // 获取要发送的图像的src

    let response = await fetch(`http://localhost:196/myupload/${MyTokenStore.myid}`, {
      method: "POST",
      headers: {
        "Content-Type": "multipart/form-data",
      },
  
      body: JSON.stringify(document.getElementById("profilepicture").value)
    })
      .then((response) => response.json())
      .catch((error) => {
        console.log("Failed", error)
      });
  
    if (response.error) {
      alert(response.message);
      return
    }
}

但我在请求中只传递了图像的 src 字符串,错误服务器显示如下:

TypeError: Cannot destructure property 'image' of 'req.files' as it is undefined.

请帮帮我,当我直接访问请求的 URL 时,请求可以正常运行(但浏览器直接显示服务器响应):

  <form :action="`http://localhost:196/myupload/${MyTokenStore.myid}`" 
   method="POST" enctype="multipart/form-data">
    <input type="file" name="image"/>
    <button type="submit">Valider mon avatar</button>
  </form>

但我无法将其放入一个函数中...

谢谢。

英文:

I searched on google and nothing...

i have a form in my view on vueJS :

  &lt;form @submit.prevent=&quot;avatar()&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
    &lt;input type=&quot;file&quot; name=&quot;profilePicture&quot; id=&quot;profilepicture&quot; &gt;
    &lt;button type=&quot;submit&quot;&gt;Valider mon avatar?&lt;/button&gt;
  &lt;/form&gt;

The user send an image.

My question is,
i want to send the image (sending by user with the form) in a function, and this function send the image to Http Request in headers ...

the api request begin with :

app.post(&#39;/myupload/:iduser&#39;, async (req, res) =&gt; {
    try{
        var { iduser } = req.params ;
        const { image } = req.file ;
        [...]

my function in my view on vuejs is actually :

async function avatar() {

    console.log(document.getElementById(&quot;profilepicture&quot;).value);
    // for having the image sending src

    let response = await fetch(`http://localhost:196/myupload/${MyTokenStore.myid}`, {
      method: &quot;POST&quot;,
      headers: {
      &quot;Content-Type&quot;: &quot;multipart/form-data&quot;,
      },
  
      body: JSON.stringify(document.getElementById(&quot;profilepicture&quot;).value)
    })
      .then((response) =&gt; response.json())
      .catch((error) =&gt; {
      console.log(&quot;Failed&quot;, error)
      });
  
    if(response.error){
      alert(response.message);
      return
    }
  }

But the only parameter i make in request is the string of the src image, and the error servor is :

TypeError: Cannot destructure property &#39;image&#39; of &#39;req.files&#39; as it is undefined.

Please, i need help, the request run when I go directly to the url of the request (but the browser directly displays the server response):

  &lt;form :action=&quot;`http://localhost:196/myupload/${MyTokenStore.myid}`&quot; 
   method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;
    &lt;input type=&quot;file&quot; name=&quot;image&quot;/&gt;
    &lt;button type=&quot;submit&quot;&gt;Valider mon avatar&lt;/button&gt;
  &lt;/form&gt;

but I fail to put it in a function...

thank you.

答案1

得分: 1

为了从Vue发送图像请求,您必须使用FormData对象。例如:

/**
 * @description - 注册用户
 */
const register = async () => {
  try {
    const fd = new FormData();

    Object.keys(user.value).forEach((key) => {
      fd.append(key, user.value[key]);
    });

    const res = await axios.post('/register', fd, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
    toast.success(res.data);
  } catch (err) {
    console.log(err);
    toast.error(err.response.data);
  }
};

在上面的代码中,在register函数中,我使用FormData来将user对象发送到后端。在以前,你应该进行设置。我将它制作成了以下示例:

const setProfileImage = (e) => {
 image_preview.value = URL.createObjectURL(e.target.files[0]);
 document.getElementById('image_preview').style.height = '150px';
 document.getElementById('image_preview').style width = '150px';
 user.value.profile_image = e.target.files[0]; // 这对你很重要。
 user.value.image = e.target.files[0].name;
};

setProfileImage接收来自Input fileevent。如果你看到代码中的注释,user.value.profile_image = e.target.files[0] 是整个文件。其余部分是用于显示图像并将名称发送到数据库。

<div class="mb-3">
  <label
      for="profile_image"
      class="bg-primary text-white rounded-3 text-center w-100 p-2 profile_image"
  >
    选择您的个人资料照片 <i class="ps-1 bi bi-card-image"></i>
  </label>
  <input
      type="file"
      class="form-control d-none"
      id="profile_image"
      placeholder="附加个人资料照片"
      @change="setProfileImage"
  />
</div>

这是我所说的Input file。事件是@change,用于正确捕获文件。

希望对您有所帮助。

英文:

To send an image from Vue doing a request you have to use a FormData object. For example:

   /**
   * @description - register user
   */
  const register = async () =&gt; {
    try {
      const fd = new FormData();

      Object.keys(user.value).forEach((key) =&gt; {
        fd.append(key, user.value[key]);
      });

      const res = await axios.post(&#39;/register&#39;, fd, {
        headers: {
          &#39;Content-Type&#39;: &#39;multipart/form-data&#39;,
        },
      });
      toast.success(res.data);
    } catch (err) {
      console.log(err);
      toast.error(err.response.data);
    }
  };

In the previous code, in register I'm using a FormData to send the user object to the backend. Previously, you should set it. I made it like the following example:

const setProfileImage = (e) =&gt; {
 image_preview.value = URL.createObjectURL(e.target.files[0]);
 document.getElementById(&#39;image_preview&#39;).style.height = &#39;150px&#39;;
 document.getElementById(&#39;image_preview&#39;).style.width = &#39;150px&#39;;
 user.value.profile_image = e.target.files[0]; // this is important for you.
 user.value.image = e.target.files[0].name;
};

setProfileImage is receiving an event from an Input file. If you see the comment I write in the code, user.value.profile_image = e.target.files[0] is the entire file. The rest is to display the image and send the name to store into the database.

       &lt;div class=&quot;mb-3&quot;&gt;
      &lt;label
          for=&quot;profile_image&quot;
          class=&quot;bg-primary text-white rounded-3 text-center w-100 p-2 profile_image&quot;
      &gt;
        Seleccione su foto de perfil &lt;i class=&quot;ps-1 bi bi-card-image&quot;&gt;&lt;/i&gt;
      &lt;/label&gt;
      &lt;input
          type=&quot;file&quot;
          class=&quot;form-control d-none&quot;
          id=&quot;profile_image&quot;
          placeholder=&quot;Adjunte su foto de perfil&quot;
          @change=&quot;setProfileImage&quot;
      /&gt;
    &lt;/div&gt;

This is the Input file what I was talking. The event is an @change to catch correctly the file.

Hope it works for you.

huangapple
  • 本文由 发表于 2023年2月14日 19:26:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75447153.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定