下载图像时出现CORS问题

时间:2017-03-21 10:45:44

标签: java cors tomcat7

我有一个API,它将base64字符串转换为图像并在Tomcat Server中写入图像。图像在调用API后成功写入,但在检索相同图像时出现错误:

  

" No' Access-Control-Allow-Origin'标题出现在请求的上   资源。因此不允许原点访问。 XMLHttpRequest的   无法加载http://hostname:4444//tmpFiles/31487660124865.jpg。没有   '访问控制允许来源'标题出现在请求的上   资源。

我的代码如下:

public Message uploadImage(Map<String, String> map) {

    // Initializing the message
    Message message = new Message();

    try {

        // Get the file data
        String fileData = map.get("file_data");

        // Split the data with the comma
        String base64Image = fileData.split(",")[1];

        // Convert the base64 input to binary
        byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image);

        BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));

        // Manipulations in File Name
        String fileName = map.get("file_name");
        String file = fileName.substring(0, fileName.indexOf("."));
        String fileExtension = fileName.substring(fileName.indexOf("."));

        // Get the current time
        Long time = new Date().getTime();

        // Write the file name with the current time to avoid redundancy
        String maniputedFileName = file + "" + time + fileExtension;
        System.out.println("manipulated file name is " + maniputedFileName);

        // Check if file name is not empty
        if (!maniputedFileName.isEmpty()) {

            // Get the root path of tomcat server
            String rootPath = System.getProperty("catalina.home");

            System.out.println("root Path:- " + rootPath);

            // File Directory/Path on tomcat server
            File fileDirectory = new File(rootPath + File.separator + "webapps/tmpFiles");

            // If file direcory does not exist
            if (!fileDirectory.exists())
                fileDirectory.mkdirs();

            File outputfile = new File(fileDirectory.getAbsolutePath() + File.separator + maniputedFileName);

            // Write created image on server
            ImageIO.write(image, "png", outputfile);

            // Set the success message
            message.setDescription("You successfully uploaded file=" + maniputedFileName);
            message.setObject(outputfile.getAbsolutePath());
            message.setValid(true);
            return message;

        }
        // Set the failure message
        else {
            message.setDescription("You failed to upload " + maniputedFileName + " because the file was empty.");
            message.setValid(false);
            return message;
        }
    }
    // Handling all exceptions
    catch (IOException e) {
        message.setDescription(e.getMessage());
        message.setValid(false);
        return message;
    }
}

web.xml是:

     <filter>
        <filter-name>tokenfilter</filter-name>
        <filter-class>com.springiot.filter.TokenFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>tokenfilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>SimpleCORSFilter</filter-name>
    <filter-class>com.springiot.filter.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SimpleCORSFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

我的tokenFilter类是:

 HttpServletResponse response = (HttpServletResponse) res;

    response.addHeader("Access-Control-Allow-Origin", "*");
    response.addHeader("Access-Control-Allow-Methods", "POST, GET,OPTIONS, DELETE");
    response.addHeader("Access-Control-Max-Age", "3600");
    response.addHeader("Access-Control-Allow-Headers",
            "Content-Type, Access-Control-Allow-Headers, Authorization,X-Requested-With,token,userKey,user_id");

6 个答案:

答案 0 :(得分:1)

您需要在web.xml CATALINA_HOME/conf中使用正确的路径名称添加过滤器,或者只添加/*。添加如下所示的过滤器

  ...

 <filter>
   <filter-name>CorsFilter</filter-name>
   <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
 </filter>
 <filter-mapping>
   <filter-name>CorsFilter</filter-name>
   <url-pattern>/*</url-pattern>
 </filter-mapping>

...

有关详细信息,请查看this官方文档

答案 1 :(得分:0)

您需要查看前端(XMLHttpRequest)方面以解决问题,而不是在Tomcat方面。

这篇关于Using CORS的文章将提供很多见解,以找出原因。

答案 2 :(得分:0)

有一些规则要遵循:

  1. 如果您向其他域发出XMLHttpRequest请求,则会出现此问题。
  2. 浏览器始终允许相同的来源,而不是其他来源的安全策略。如果浏览器发现任何不同的请求,那么它将阻止你。
  3. 这个问题 [如何使用CORS代理来解决“No Access-Control-Allow-Origin标题”问题] 在这里得到解答:https://stackoverflow.com/a/43881141/2293534

      

    CORS安全 - 通用允许

         
        
    1. 设置&#39; Access-Control-Allow-Origin&#39;标题为*
    2.   
    3. 有效地将内容转换为公共资源,允许从任何域进行访问。
    4.         

      <强>方案:

           
          
      1. 攻击者可以通过诱使用户访问攻击者控制的网站,从已将此标头设置为*的Intranet网站窃取数据   互联网。
      2.   
      3. 当受害者导航到攻击者控制的网站时,攻击者可以通过受害者的浏览器对其他远程应用程序执行攻击。
      4.   

    我在这里给出了答案:Is this CORS handler safe?你可以在这里查看CORS。它会澄清你的更多。

    资源链接:

    1. Cross-Origin XMLHttpRequest
    2. Why does my JavaScript get a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error when Postman does not?

答案 3 :(得分:0)

如果您可以访问tomcat服务器中的管道,可以尝试使用HTTPS提供API,那么CORS就不会发生。

OR

你可以禁用我不推荐的tomcat服务器中的cors

答案 4 :(得分:0)

CORS问题?使用代理并遵守规则。通过更改标头,您将删除为避免特定类型的攻击而采取的安全措施。如果您正在做任何需要保护的事情,这是一个坏主意。

在代理处,您可以拦截请求并更改所需标头中的任何内容,并在需要时重写响应标头,而不会产生风险。

从您的错误消息“http://:4444//tmpFiles/31487660124865.jpg”中,网址显然有问题。请发布请求的代码。

@SkyWalker对他的回答是正确的。我怀疑一旦你向我们提供了其余的代码,很明显域或协议和域正在发生变化。如果是这种情况并且您不希望自己变得容易受到攻击,只需通过代理终止有效ssl证书的代理运行它。 (并不意味着你不应该保护到上游的流量)

Nginx适用于这类任务。但是选择你的代理人..那里有很多人。

答案 5 :(得分:0)

如果使XMLHttpRequest导致问题,则不要使用它,而是考虑仅将数据(使用HttpURLConnection)提取到本地bytearray中。现在解码(显示)从局部变量(例如:字节数组)加载的图像以避免CORS。

此外,我习惯使用以下网址:http://host:port/address/但您的网址为http://:port//,因此我不明白如何通过仅使用端口来访问网络(http)服务器strong>没有服务器地址。这应该导致URL错误,但你必须以某种方式到达文件目的地,因为CORS碰巧保护媒体...

以下代码可能值得在空白/新测试项目中尝试:

(PS:没有提供类似http://server:port/tmpFiles/image.jpg的可测试链接,因此使用如图所示)

Image image = null;

try 
{
    URL url = new URL("http://:4444//tmpFiles/31487660124865.jpg");
    image = ImageIO.read(url);
} 
catch (IOException e) { e.printStackTrace(); }

JFrame frame = new JFrame("StackOverflow test");
JLabel label = new JLabel(new ImageIcon(image));
frame.setSize(500, 500); 
frame.add(label); frame.setVisible(true);

相关进口商品:

import javax.swing.ImageIcon;
import javax.swing.JFrame;          import javax.swing.JLabel;
import java.awt.Image;              import javax.imageio.ImageIO;
import java.net.HttpURLConnection;  import java.net.URL;