1. 程式人生 > >Umeditor結合Spring Restful解決圖片上傳跨域問題

Umeditor結合Spring Restful解決圖片上傳跨域問題

專案中編輯器採用了Umeditor,但是由於跨域的問題,上傳圖片不能正常使用,本文解決了Spring應用的跨域問題,Spring的專案均可以參考。

專案背景

(任何不談背景的解決方案都是耍流)
Umeditor+spring mvc restful,前後端分離,所以域名也不同,存在跨域的問題,前端a.com,後端b.com

之前在很多地方看到了各種解決方法,然而有的是和我的情況不一致,有的是根本沒有說明自己的專案背景,以及我不是很明白百度的官方文件為何是給出了後端的配置而不是給出對後端的要求即可?一個前端團隊為何還要干預後端的事情呢?在前後端分離的情況下,難道不應該是前後端遵循統一的規範就好了嗎?

解決方案

首先,後端配置允許跨域請求,在某個有@Configuration的配置類中新增:

 @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry)          
                registry.addMapping("/**")
                        .allowedOrigins
("*") .allowedMethods("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "TRACE"); } }; }

之後修改umeditor.config.js

 //圖片上傳配置區
        imageUrl:"http://b.com/picture"             //圖片上傳提交地址
        imagePath:"http://b.com/file/"                      //圖片修正地址,引用了fixedImagePath,如有特殊需求,可自行配置
imageFieldName:"upfile" //圖片資料的key,若此處修改,需要在後臺對應檔案修改對應引數

解釋:imageUrl為圖片上傳的提交地址,而引數的名字(後臺匹配的requestparam)是imageFieldName,imagePath是圖片修正地址,意思是圖片上傳到後臺後,會返回一串字串(restful形式,返回到response中),其中的url欄位將會拼接在imagePath後形成picsrc,這個picsrc會成為圖片的請求地址(即http://b.com/file/url )

最後,撰寫後臺程式碼如下:

package com.uvlab.sitespot.io;

import com.uvlab.sitespot.init.JxAppFoundation;
import com.uvlab.sitespot.service.JxAppService;
import com.uvlab.sitespot.service.fdb.JxNode;
import com.wordnik.swagger.annotations.ApiOperation;
import org.json.JSONObject;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by Jys on 2016/5/14 0014.
 */
@CrossOrigin
@RestController
public class JxWikiController {

    @RequestMapping(value = "/picture",method = RequestMethod.POST)
    public String uploadPicture(@RequestParam("upfile") MultipartFile file,HttpServletRequest request,HttpServletResponse response){

        response.setContentType("text/html; charset=utf-8"); //以下為允許跨域的一些設定
        response.setHeader("Access-Control-Allow-Origin","*");
        response.setHeader("x-frame-options", "ALLOW-FROM *");
        response.addHeader("Content-Security-Policy","frame-ancestors *");
        response.setHeader("Access-Control-Allow-Headers","Access-Control");
        String originname=file.getOriginalFilename();
        int doc=originname.lastIndexOf(".");
        String suffix=originname.substring(doc); //得到字尾名
        String uuid= UUID.randomUUID().toString(); //使用uuid命名新檔案
        String finalname= JxAppFoundation.WikiFile+uuid+suffix; //新檔案的儲存位置全路徑名
        BufferedOutputStream stream = null;
        try {
            stream = new BufferedOutputStream(
                    new FileOutputStream(new File(finalname)));

            FileCopyUtils.copy(file.getInputStream(), stream);
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        long size=file.getSize();
        String ret=String.format("{\"originalName\":\"%s\"," +
                "\"name\":\"%s\"," +
                "\"url\":\"%s\"," +
                "\"size\":\"%s\"," +
                "\"type\":\"%s\"," +
                "\"state\":\"%s\"}",
                originname,uuid+suffix,uuid+suffix,Long.toString(size),suffix,"SUCCESS"); //返回字串,返回的url引數為新檔名
        return ret;

    }

    @RequestMapping(value = "/file/{path:.+}",method = RequestMethod.GET)//這裡的path即上一步返回的url
    public void getPicture(@PathVariable(value = "path")String path,HttpServletResponse response){
        FileInputStream in = null;
        OutputStream out = null;
        try {
            File file = new File(JxAppFoundation.WikiFile + path); //獲取檔案
            in = new FileInputStream(file);
            byte[] b = new byte[(int) file.length()];
            in.read(b);
            in.close();
            response.setContentType("image/*");
            out = response.getOutputStream(); //檔案寫入到response
            out.write(b);
            out.flush();
            out.close();
        } catch (IllegalArgumentException | SecurityException | IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null)
                    in.close();
                if (out != null)
                    out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


}

總結

以上方案解決了圖片的插入和顯示問題,對於跨域的處理,由於umeditor對於拖入圖片和點選開啟對話方塊選擇的處理方法不同,拖入和貼上都可以解決,但是對於點選開啟插入圖片的跨域問題仍未解決,待解決後修改本篇文章.各位看官如有好的方案歡迎在評論中指出,謝謝大家。

這裡寫圖片描述