我有一个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");
答案 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)
有一些规则要遵循:
这个问题 [如何使用CORS代理来解决“No Access-Control-Allow-Origin标题”问题] 在这里得到解答:https://stackoverflow.com/a/43881141/2293534
CORS安全 - 通用允许
- 设置&#39; Access-Control-Allow-Origin&#39;标题为*
- 有效地将内容转换为公共资源,允许从任何域进行访问。
醇><强>方案:强>
- 攻击者可以通过诱使用户访问攻击者控制的网站,从已将此标头设置为*的Intranet网站窃取数据 互联网。
- 当受害者导航到攻击者控制的网站时,攻击者可以通过受害者的浏览器对其他远程应用程序执行攻击。
醇>
我在这里给出了答案:Is this CORS handler safe?你可以在这里查看CORS。它会澄清你的更多。
答案 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;